annotate common/EditDistance.cpp @ 53:bcea875d8d2f tip

More build fixes
author Chris Cannam
date Thu, 16 Oct 2014 19:03:51 +0100
parents 7d8a6167febb
children
rev   line source
Chris@11 1
Chris@11 2 #include "EditDistance.h"
Chris@17 3 #include <algorithm>
Chris@11 4
Chris@13 5 #include <cstdlib> // abs
Chris@13 6
Chris@11 7 namespace ClassicalData
Chris@11 8 {
Chris@11 9
Chris@11 10 int
Chris@13 11 EditDistance::calculate(QString a, QString b, int threshold)
Chris@11 12 {
Chris@11 13 // Note: restricted Damerau-Levenshtein edit distance, or
Chris@11 14 // Levenshtein if NoTransposition
Chris@11 15
Chris@11 16 int al = a.length() + 1;
Chris@11 17 int bl = b.length() + 1;
Chris@11 18
Chris@13 19 if (threshold > 0 && abs(al - bl) > threshold) return threshold + 1;
Chris@13 20
Chris@11 21 int *currRow = (int *)alloca(sizeof(int) * bl);
Chris@11 22 int *prevRow = (int *)alloca(sizeof(int) * bl);
Chris@11 23 int *ppreRow = (int *)alloca(sizeof(int) * bl);
Chris@11 24 int *tmp = 0;
Chris@11 25
Chris@11 26 for (int i = 0; i < bl; ++i) {
Chris@28 27 prevRow[i] = i;
Chris@11 28 }
Chris@11 29
Chris@11 30 for (int j = 1; j < al; ++j) {
Chris@28 31 currRow[0] = j;
Chris@13 32 bool stillAcceptable = (threshold == 0);
Chris@11 33 for (int i = 1; i < bl; ++i) {
Chris@11 34 if (a[j-1] == b[i-1]) {
Chris@11 35 currRow[i] = prevRow[i-1];
Chris@11 36 } else {
Chris@11 37 int horizontal, vertical, diagonal;
Chris@28 38 horizontal = currRow[i-1] + 1;
Chris@28 39 diagonal = prevRow[i-1] + 1;
Chris@28 40 if (i+1 == bl) vertical = prevRow[i] + 1;
Chris@28 41 else vertical = prevRow[i] + 1;
Chris@11 42 currRow[i] =
Chris@11 43 std::min(horizontal, std::min(vertical, diagonal));
Chris@11 44 }
Chris@11 45 if (m_transpositionMode == RestrictedTransposition) {
Chris@11 46 if (i > 1 && j > 1 && a[i-1]==b[j-2] && a[i-2]==b[j-1]) {
Chris@28 47 currRow[i] = std::min(currRow[i], ppreRow[i-2] + 1);
Chris@11 48 }
Chris@11 49 }
Chris@13 50 if (threshold > 0 && currRow[i] <= threshold) {
Chris@13 51 stillAcceptable = true;
Chris@13 52 }
Chris@11 53 }
Chris@13 54 if (!stillAcceptable) return threshold + 1;
Chris@11 55 tmp = ppreRow;
Chris@11 56 ppreRow = prevRow;
Chris@11 57 prevRow = currRow;
Chris@11 58 currRow = tmp;
Chris@11 59 }
Chris@11 60
Chris@11 61 int result = prevRow[bl-1];
Chris@11 62 return result;
Chris@11 63 }
Chris@11 64
Chris@11 65 }
Chris@11 66