/src/aspell/modules/speller/default/editdist.cpp
Line | Count | Source |
1 | | |
2 | | #include <cstring> |
3 | | |
4 | | #include "editdist.hpp" |
5 | | #include "matrix.hpp" |
6 | | #include "vararray.hpp" |
7 | | |
8 | | // edit_distance is implemented using a straight forward dynamic |
9 | | // programming algorithm with out any special tricks. Its space |
10 | | // usage AND running time is tightly asymptotically bounded by |
11 | | // strlen(a)*strlen(b) |
12 | | |
13 | | namespace aspeller { |
14 | | |
15 | | short edit_distance(ParmString a0, ParmString b0, |
16 | | const EditDistanceWeights & w) |
17 | 1.80M | { |
18 | 1.80M | int a_size = a0.size() + 1; |
19 | 1.80M | int b_size = b0.size() + 1; |
20 | 1.80M | VARARRAY(short, e_d, a_size * b_size); |
21 | 1.80M | ShortMatrix e(a_size,b_size,e_d); |
22 | 1.80M | e(0, 0) = 0; |
23 | 9.54M | for (int j = 1; j != b_size; ++j) |
24 | 7.74M | e(0, j) = e(0, j-1) + w.del1; |
25 | 1.80M | const char * a = a0.str() - 1; |
26 | 1.80M | const char * b = b0.str() - 1; |
27 | 1.80M | short te; |
28 | 18.5M | for (int i = 1; i != a_size; ++i) { |
29 | 16.7M | e(i, 0) = e(i-1, 0) + w.del2; |
30 | 106M | for (int j = 1; j != b_size; ++j) { |
31 | 89.9M | if (a[i] == b[j]) { |
32 | | |
33 | 4.49M | e(i, j) = e(i-1, j-1); |
34 | | |
35 | 85.4M | } else { |
36 | | |
37 | 85.4M | e(i, j) = w.sub + e(i-1, j-1); |
38 | | |
39 | 85.4M | if (i != 1 && j != 1 && |
40 | 63.9M | a[i] == b[j-1] && a[i-1] == b[j]) |
41 | 123k | { |
42 | 123k | te = w.swap + e(i-2, j-2); |
43 | 123k | if (te < e(i, j)) e(i, j) = te; |
44 | 123k | } |
45 | | |
46 | 85.4M | te = w.del1 + e(i-1, j); |
47 | 85.4M | if (te < e(i, j)) e(i, j) = te; |
48 | 85.4M | te = w.del2 + e(i, j-1); |
49 | 85.4M | if (te < e(i, j)) e(i, j) = te; |
50 | | |
51 | 85.4M | } |
52 | 89.9M | } |
53 | 16.7M | } |
54 | 1.80M | return e(a_size-1, b_size-1); |
55 | 1.80M | } |
56 | | } |