liblevenshtein 4.0.0
A library for generating Finite State Transducers based on Levenshtein Automata.
Loading...
Searching...
No Matches
position_transition.cpp
Go to the documentation of this file.
1#include <cstdint>
3
4namespace liblevenshtein {
5
6auto index_of(std::vector<bool> &characteristic_vector, std::size_t k,
7 std::size_t i) -> std::size_t {
8 for (std::size_t j = 0; j < k; j += 1) {
9 if (characteristic_vector[i + j]) {
10 return j;
11 }
12 }
13 return SIZE_MAX;
14}
15
16template <>
18 std::size_t n, Position *position, std::vector<bool> &characteristic_vector,
19 std::size_t offset) -> std::vector<Position *> {
20
21 std::size_t i = position->term_index();
22 std::size_t e = position->num_errors();
23 std::size_t h = i - offset;
24 std::size_t w = characteristic_vector.size();
25
26 if (e < n) {
27 if (h + 2 <= w) {
28 std::size_t a = (n - e < SIZE_MAX)
29 ? n - e + 1
30 : SIZE_MAX;
31 std::size_t b = w - h;
32 std::size_t k = (a < b) ? a : b;
33 std::size_t j = index_of(characteristic_vector, k, h);
34
35 if (j == 0) {
36 return {
37 new Position(i + 1, e)
38 };
39 }
40
41 if (j != SIZE_MAX) {
42 return {
43 new Position(i, e + 1),
44 new Position(i + 1, e + 1),
45 new Position(i + j + 1, e + j)
46 };
47 }
48
49 return {
50 new Position(i, e + 1),
51 new Position(i + 1, e + 1)
52 };
53 }
54
55 if (h + 1 == w) {
56 if (characteristic_vector[h]) {
57 return {
58 new Position(i + 1, e)
59 };
60 }
61
62 return {
63 new Position(i, e + 1),
64 new Position(i + 1, e + 1)
65 };
66 }
67
68 return {
69 new Position(i, e + 1)
70 };
71 }
72
73 if (e == n && h + 1 <= w && characteristic_vector[h]) {
74 return {
75 new Position(i + 1, n)
76 };
77 }
78
79 return {};
80}
81
82// NOLINTBEGIN(readability-function-cognitive-complexity)
83template <>
85 std::size_t n, Position *position, std::vector<bool> &characteristic_vector,
86 std::size_t offset) -> std::vector<Position *> {
87
88 std::size_t i = position->term_index();
89 std::size_t e = position->num_errors();
90 bool t = position->is_special();
91 std::size_t h = i - offset;
92 std::size_t w = characteristic_vector.size();
93
94 if (e == 0 && 0 < n) {
95 if (h + 2 <= w) {
96 std::size_t a = (n - e < SIZE_MAX)
97 ? n - e + 1
98 : SIZE_MAX;
99 std::size_t b = w - h;
100 std::size_t k = (a < b) ? a : b;
101 std::size_t j = index_of(characteristic_vector, k, h);
102
103 switch (j) {
104 case 0:
105 return {
106 new Position(i + 1, 0)
107 };
108 case 1:
109 return {
110 new Position(i, 1),
111 new Position(i, 1, true),
112 new Position(i + 1, 1),
113 new Position(i + 2, 1)
114 };
115 case SIZE_MAX:
116 return {
117 new Position(i, 1),
118 new Position(i + 1, 1)
119 };
120 default:
121 return {
122 new Position(i, 1),
123 new Position(i + 1, 1),
124 new Position(i + j + 1, j)
125 };
126 }
127 }
128
129 if (h + 1 == w) {
130 if (characteristic_vector[h]) {
131 return {
132 new Position(i + 1, 0)
133 };
134 }
135
136 return {
137 new Position(i, 1),
138 new Position(i + 1, 1)
139 };
140 }
141
142 return {
143 new Position(i, 1)
144 };
145 }
146
147 if (1 <= e && e < n) {
148 if (h + 2 <= w) {
149 if (!t) {
150 std::size_t a = (n - e < SIZE_MAX)
151 ? n - e + 1
152 : SIZE_MAX;
153 std::size_t b = w - h;
154 std::size_t k = (a < b) ? a : b;
155 std::size_t j = index_of(characteristic_vector, k, h);
156
157 switch (j) {
158 case 0:
159 return {
160 new Position(i + 1, e)
161 };
162 case 1:
163 return {
164 new Position(i, e + 1),
165 new Position(i, e + 1, true),
166 new Position(i + 1, e + 1),
167 new Position(i + 2, e + 1)
168 };
169 case SIZE_MAX:
170 return {
171 new Position(i, e + 1),
172 new Position(i + 1, e + 1)
173 };
174 default:
175 return {
176 new Position(i, e + 1),
177 new Position(i + 1, e + 1),
178 new Position(i + j + 1, e + j)
179 };
180 }
181 }
182
183 if (characteristic_vector[h]) {
184 return {
185 new Position(i + 2, e)
186 };
187 }
188
189 return {};
190 }
191
192 if (h + 1 == w) {
193 if (characteristic_vector[h]) {
194 return {
195 new Position(i + 1, e)
196 };
197 }
198
199 return {
200 new Position(i, e + 1),
201 new Position(i + 1, e + 1)
202 };
203 }
204
205 return {
206 new Position(i, e + 1)
207 };
208 }
209
210 if (h + 1 <= w && !t) {
211 if (characteristic_vector[h]) {
212 return {
213 new Position(i + 1, n)
214 };
215 }
216
217 return {};
218 }
219
220 if (h + 2 <= w && t && characteristic_vector[h]) {
221 return {
222 new Position(i + 2, n)
223 };
224 }
225
226 return {};
227}
228// NOLINTEND(readability-function-cognitive-complexity)
229
230// NOLINTBEGIN(readability-function-cognitive-complexity)
231template <>
233 std::size_t n, Position *position, std::vector<bool> &characteristic_vector,
234 std::size_t offset) -> std::vector<Position *> {
235
236 std::size_t i = position->term_index();
237 std::size_t e = position->num_errors();
238 bool s = position->is_special();
239 std::size_t h = i - offset;
240 std::size_t w = characteristic_vector.size();
241
242 if (e == 0 && 0 < n) {
243 if (h + 2 <= w) {
244 if (characteristic_vector[h]) {
245 return {
246 new Position(i + 1, e)
247 };
248 }
249
250 return {
251 new Position(i, e + 1),
252 new Position(i, e + 1, true),
253 new Position(i + 1, e + 1),
254 new Position(i + 2, e + 1)
255 };
256 }
257
258 if (h + 1 == w) {
259 if (characteristic_vector[h]) {
260 return {
261 new Position(i + 1, e)
262 };
263 }
264
265 return {
266 new Position(i, e + 1),
267 new Position(i, e + 1, true),
268 new Position(i + 1, e + 1)
269 };
270 }
271
272 return {
273 new Position(i, e + 1)
274 };
275 }
276
277 if (e < n) {
278 if (h + 2 <= w) {
279 if (!s) {
280 if (characteristic_vector[h]) {
281 return {
282 new Position(i + 1, e)
283 };
284 }
285
286 return {
287 new Position(i, e + 1),
288 new Position(i, e + 1, true),
289 new Position(i + 1, e + 1),
290 new Position(i + 2, e + 1)
291 };
292 }
293
294 return {
295 new Position(i + 1, e)
296 };
297 }
298
299 if (h + 1 == w) {
300 if (!s) {
301 if (characteristic_vector[h]) {
302 return {
303 new Position(i + 1, e)
304 };
305 }
306
307 return {
308 new Position(i, e + 1),
309 new Position(i, e + 1, true),
310 new Position(i + 1, e + 1)
311 };
312 }
313
314 return {
315 new Position(i + 1, e)
316 };
317 }
318
319 return {
320 new Position(i, e + 1)
321 };
322 }
323
324 if (h + 1 <= w) {
325 if (!s) {
326 if (characteristic_vector[h]) {
327 return {
328 new Position(i + 1, n)
329 };
330 }
331
332 return {};
333 }
334
335 return {
336 new Position(i + 1, e)
337 };
338 }
339
340 return {};
341}
342// NOLINTEND(readability-function-cognitive-complexity)
343
344} // namespace liblevenshtein
Represents a location within the Levenshtein automaton.
Definition position.h:11
auto term_index() const -> std::size_t
Returns the current position in the dictionary term.
Definition position.cpp:23
void query(ll::Dawg *dawg, const std::string &query_term, std::size_t max_distance)
Definition main.cpp:25
Various utilities regarding Levenshtein transducers.
Definition namespaces.dox:9
auto position_transition< Algorithm::TRANSPOSITION >(std::size_t n, Position *position, std::vector< bool > &characteristic_vector, std::size_t offset) -> std::vector< Position * >
Returns the closure over possible next Positions that are reachable from the current Position by adva...
auto index_of(std::vector< bool > &characteristic_vector, std::size_t k, std::size_t i) -> std::size_t
Returns the first index of the desired character in the characteristic vector, beginning at the offse...
auto position_transition< Algorithm::STANDARD >(std::size_t n, Position *position, std::vector< bool > &characteristic_vector, std::size_t offset) -> std::vector< Position * >
Returns the closure over possible next Positions that are reachable from the current Position by adva...
auto position_transition< Algorithm::MERGE_AND_SPLIT >(std::size_t n, Position *position, std::vector< bool > &characteristic_vector, std::size_t offset) -> std::vector< Position * >
Returns the closure over possible next Positions that are reachable from the current Position by adva...