annotate common/EditDistance.cpp @ 11:98047b91b09d classical-rdf

* Add "proper" composer name matching from user input. Needs to be faster though
author Chris Cannam
date Thu, 18 Feb 2010 18:16:43 +0000
parents
children a1d67e136c30
rev   line source
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