Каковы некоторые алгоритмы сравнения того, насколько похожи две строки?
мне нужно сравнить строки, чтобы решить, представляют ли они одно и то же. Это относится к названиям дел, введенным людьми, где аббревиатуры и другие мелкие детали могут отличаться. Например, рассмотрим следующие два названия:
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. Например, преобразуйте две строки в триграммы слов (обычно в нижнем регистре) и сравните процент из них, которые равны друг другу.
ваша задача-определить минимальный процент сходства.