Каковы некоторые алгоритмы сравнения того, насколько похожи две строки?

мне нужно сравнить строки, чтобы решить, представляют ли они одно и то же. Это относится к названиям дел, введенным людьми, где аббревиатуры и другие мелкие детали могут отличаться. Например, рассмотрим следующие два названия:

std::string first = "Henry C. Harper v. The Law Offices of Huey & Luey, LLP";

против:

std::string second = "Harper v. The Law Offices of Huey & Luey, LLP";

человек может быстро оценить, что это, скорее всего, один и тот же. Текущий подход, который я принял, заключается в нормализации строк путем нижнего регистра всех букв и удаления всех знаков препинания и пробелы давая:

std::string firstNormalized = "henrycharpervthelawofficesofhueylueyllp";

и:

std::string secondNormalized = "harpervthelawofficesofhueylueyllp";

сравнение в этом случае одно является подпоследовательностью другого, но вы можете представить себе другие более сложные вариации, где это не обязательно происходит, но у них есть значительные подпоследовательности. Могут также быть случайные ошибки ввода человека, такие как транспонированные буквы и орфографические ошибки.

возможно, какая-то программа для различения символов может помочь? Я видел хорошие программы line diff для сравнения различия в коде, который нужно проверить, есть ли что-то подобное на основе символов, может быть, в boost? Если бы вы могли подсчитать общее количество последовательных символов и принять отношение к символам без разделения, возможно, это было бы хорошей эвристикой?

В конце концов, мне нужно логическое решение о том, чтобы считать их одинаковыми или нет. Он не должен быть совершенным, но в идеале он должен редко ошибаться.

какой алгоритм я могу использовать, что даст мне своего рода количественная оценка того, насколько похожи две строки друг на друга, которые я могу затем преобразовать в ответ "Да/нет" с помощью некоторой эвристики?

3 ответов


то, что вы ищете, называется Строку Метрика алгоритмов. Там значительное количество их, много с подобными характеристиками. Среди наиболее популярных:

  • Расстояние Левенштейна: минимальное количество односимвольных изменений, необходимых для изменения одного слова в другое. Строки не должны быть одинаковой длины
  • Хэмминга : число символы, которые различаются в двух строках одинаковой длины.
  • Смита–Ватермана: семейство алгоритмов для вычисления сходства переменных суб-последовательностей.
  • Sørensen-Коэффициент Кости: алгоритм подобия, который вычисляет разностные коэффициенты смежных пар символов.

посмотрите на них, а также на других на страница wiki по теме.


Damerau Levenshtein расстояние - еще один алгоритм сравнения двух строк, похожий на алгоритм расстояния Левенштейна. Разница между ними в том, что он также может проверять транспозиции между символами и, следовательно, может дать лучший результат для исправления ошибок.

например: расстояние Левенштейна между night и nigth is 2 но Дамерау Левенштейн расстояние между night и nigth будет 1, потому что это просто своп пара персонажей.


для этого можно использовать ngrams. Например, преобразуйте две строки в триграммы слов (обычно в нижнем регистре) и сравните процент из них, которые равны друг другу.

ваша задача-определить минимальный процент сходства.

http://en.wikipedia.org/wiki/N-gram