Chris@11
|
1
|
Chris@11
|
2 #include "EditDistance.h"
|
Chris@11
|
3
|
Chris@11
|
4 namespace ClassicalData
|
Chris@11
|
5 {
|
Chris@11
|
6
|
Chris@11
|
7 int
|
Chris@11
|
8 EditDistance::calculate(QString a, QString b)
|
Chris@11
|
9 {
|
Chris@11
|
10 // Note: restricted Damerau-Levenshtein edit distance, or
|
Chris@11
|
11 // Levenshtein if NoTransposition
|
Chris@11
|
12
|
Chris@11
|
13 int al = a.length() + 1;
|
Chris@11
|
14 int bl = b.length() + 1;
|
Chris@11
|
15
|
Chris@11
|
16 int *currRow = (int *)alloca(sizeof(int) * bl);
|
Chris@11
|
17 int *prevRow = (int *)alloca(sizeof(int) * bl);
|
Chris@11
|
18 int *ppreRow = (int *)alloca(sizeof(int) * bl);
|
Chris@11
|
19 int *tmp = 0;
|
Chris@11
|
20
|
Chris@11
|
21 for (int i = 0; i < bl; ++i) {
|
Chris@11
|
22 prevRow[i] = i * m_editPenalty;
|
Chris@11
|
23 }
|
Chris@11
|
24
|
Chris@11
|
25 for (int j = 1; j < al; ++j) {
|
Chris@11
|
26 currRow[0] = j * m_editPenalty;
|
Chris@11
|
27 for (int i = 1; i < bl; ++i) {
|
Chris@11
|
28 if (a[j-1] == b[i-1]) {
|
Chris@11
|
29 currRow[i] = prevRow[i-1];
|
Chris@11
|
30 } else {
|
Chris@11
|
31 int horizontal, vertical, diagonal;
|
Chris@11
|
32 horizontal = currRow[i-1] + m_editPenalty;
|
Chris@11
|
33 diagonal = prevRow[i-1] + m_editPenalty;
|
Chris@11
|
34 if (i+1 == bl) vertical = prevRow[i] + m_suffixPenalty;
|
Chris@11
|
35 else vertical = prevRow[i] + m_editPenalty;
|
Chris@11
|
36 currRow[i] =
|
Chris@11
|
37 std::min(horizontal, std::min(vertical, diagonal));
|
Chris@11
|
38 }
|
Chris@11
|
39 if (m_transpositionMode == RestrictedTransposition) {
|
Chris@11
|
40 if (i > 1 && j > 1 && a[i-1]==b[j-2] && a[i-2]==b[j-1]) {
|
Chris@11
|
41 currRow[i] = std::min(currRow[i],
|
Chris@11
|
42 ppreRow[i-2] + m_editPenalty);
|
Chris@11
|
43 }
|
Chris@11
|
44 }
|
Chris@11
|
45 }
|
Chris@11
|
46 tmp = ppreRow;
|
Chris@11
|
47 ppreRow = prevRow;
|
Chris@11
|
48 prevRow = currRow;
|
Chris@11
|
49 currRow = tmp;
|
Chris@11
|
50 }
|
Chris@11
|
51
|
Chris@11
|
52 int result = prevRow[bl-1];
|
Chris@11
|
53 if (m_normalise) {
|
Chris@11
|
54 result = result / m_editPenalty;
|
Chris@11
|
55 if (result % m_editPenalty) ++result;
|
Chris@11
|
56 }
|
Chris@11
|
57 return result;
|
Chris@11
|
58 }
|
Chris@11
|
59
|
Chris@11
|
60 }
|
Chris@11
|
61
|