To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Revision:

root / common / EditDistance.cpp

History | View | Annotate | Download (1.52 KB)

1

    
2
#include "EditDistance.h"
3
#include <algorithm>
4

    
5
#include <cstdlib> // abs
6

    
7
namespace ClassicalData
8
{
9

    
10
int
11
EditDistance::calculate(QString a, QString b, int threshold)
12
{
13
    // Note: restricted Damerau-Levenshtein edit distance, or
14
    // Levenshtein if NoTransposition
15

    
16
    int al = a.length() + 1;
17
    int bl = b.length() + 1;
18

    
19
    if (threshold > 0 && abs(al - bl) > threshold) return threshold + 1;
20

    
21
    int *currRow = (int *)alloca(sizeof(int) * bl);
22
    int *prevRow = (int *)alloca(sizeof(int) * bl);
23
    int *ppreRow = (int *)alloca(sizeof(int) * bl);
24
    int *tmp = 0;
25
    
26
    for (int i = 0; i < bl; ++i) {
27
        prevRow[i] = i;
28
    }
29

    
30
    for (int j = 1; j < al; ++j) {
31
        currRow[0] = j;
32
        bool stillAcceptable = (threshold == 0);
33
        for (int i = 1; i < bl; ++i) {
34
            if (a[j-1] == b[i-1]) {
35
                currRow[i] = prevRow[i-1];
36
            } else {
37
                int horizontal, vertical, diagonal;
38
                horizontal = currRow[i-1] + 1;
39
                diagonal   = prevRow[i-1] + 1;
40
                if (i+1 == bl) vertical = prevRow[i] + 1;
41
                else vertical = prevRow[i] + 1;
42
                currRow[i] =
43
                    std::min(horizontal, std::min(vertical, diagonal));
44
            }
45
            if (m_transpositionMode == RestrictedTransposition) {
46
                if (i > 1 && j > 1 && a[i-1]==b[j-2] && a[i-2]==b[j-1]) {
47
                    currRow[i] = std::min(currRow[i], ppreRow[i-2] + 1);
48
                }
49
            }
50
            if (threshold > 0 && currRow[i] <= threshold) {
51
                stillAcceptable = true;
52
            }
53
        }
54
        if (!stillAcceptable) return threshold + 1;
55
        tmp = ppreRow;
56
        ppreRow = prevRow;
57
        prevRow = currRow;
58
        currRow = tmp;
59
    }
60

    
61
    int result = prevRow[bl-1];
62
    return result;
63
}
64

    
65
}
66