Я использую алгоритм Distance Levenshtein в С++ для сравнения двух строк, чтобы измерить, насколько они близки друг к другу. Однако простой алгоритм Levenshtein Distance не отличает границы слов как ограниченные пробелами. Это приводит к вычислениям меньшего расстояния, чем я хочу. Я сравниваю названия, чтобы увидеть, насколько они близки друг к другу, и я хочу, чтобы алгоритм не учитывал символы как совпадающие, если они исходили из нескольких слов.
Например, если я сравниваю эти две строки, я получаю следующий результат: +
, обозначающий соответствие, и -
, обозначающий несоответствие:
Al Chertoff Et
Al Church Department of finance Et
+++++------+--++-----++-+------+++
Al Ch e rt of f Et
Я получаю дистанцию 20 с словом "Chertoff"
, сопоставляющим четыре слова "Church Department of finance"
, тогда как я действительно хочу, чтобы их рассматривали дальше друг от друга, не позволяя символам соответствовать более чем одному слову и получить расстояние 25, когда слово "Chertoff"
наиболее соответствует одному слову "Department"
, с тремя символами, соответствующими:
Al Chertoff Et
Al Church Department of finance Et
+++--------+--++---------------+++
Al e rt Et
Ch off
Как я могу адаптировать Levenshtein Distance для выполнения этого или есть другой алгоритм расстояния, который лучше подходит для этого? Возможно, используя расстояние Левенштейна на каждом слове в отдельном слове, и выбирая слово с наименьшим расстоянием? Однако, что, если совпадение одного слова с глубиной в строке привело к тому, что последующие слова соответствовали плохо, потому что их совпадения были лучше всего в строке? Может ли это быть сделано с расстоянием Левенштейна, подходящим для уровня слов?
Например, кратчайшее расстояние по этой идее для следующего более сложного примера - 20:
Al Chertoff Deport Et
Al Church Department of finance Et
+++++----++++-++---------------+++
Al Ch Dep rt Et
ertoff o
Вместо максимизации "Chertoff"
совпадения и получения более длинного расстояния 24:
Al Chertoff Deport Et
Al Church Department of finance Et
+++--------+--++-----+---------+++
Al e rt o Et
Ch off
Dep rt
Моя текущая реализация расстояния Левенштейна такова:
size_t
levenshtein_distance(const std::string& a_compare1,
const std::string& a_compare2) {
const size_t length1 = a_compare1.size();
const size_t length2 = a_compare2.size();
std::vector<size_t> curr_col(length2 + 1);
std::vector<size_t> prev_col(length2 + 1);
// Prime the previous column for use in the following loop:
for (size_t idx2 = 0; idx2 < length2 + 1; ++idx2) {
prev_col[idx2] = idx2;
}
for (size_t idx1 = 0; idx1 < length1; ++idx1) {
curr_col[0] = idx1 + 1;
for (size_t idx2 = 0; idx2 < length2; ++idx2) {
const size_t compare = a_compare1[idx1] == a_compare2[idx2] ? 0 : 1;
curr_col[idx2 + 1] = std::min(std::min(curr_col[idx2] + 1,
prev_col[idx2 + 1] + 1),
prev_col[idx2] + compare);
}
curr_col.swap(prev_col);
}
return prev_col[length2];
}