Збіжіть два рядки, але допускайте ступінь помилки


10

Як я можу зіставити два рядки, але в той же час допускати, щоб кількість X символів була невірною у збігу. Кількість помилок має бути керованою змінною.

Хоча кількість символів X не може збігатися в рядку, повинно бути обмеження щодо кількості запуску в послідовності. З огляду на два рядки, я можу дозволити 5 символів бути різними, але не більше ніж 2 підряд.

Я шукаю рекомендований алгоритм для порівняння цих двох рядків, або, можливо, для цього вже є відоме рішення.


4
Відстань Левенштейна може бути на що слід поглянути, хоча специфіка "не більше 2 підряд" не є частиною цього алгоритму. На сторінці див. Також є багато інших пов'язаних алгоритмів, які можуть бути тим, що ви шукаєте.

@MichaelT Якби у мене було щось подібне, воно б точно відповідало моїм потребам. Дякую.
Реакційний

@MichaelT Я знайшов це> dotnetperls.com/levenshtein Ви повинні сказати, що як відповідь це вирішило мої проблеми.
Реакційний

Ви можете подивитися на відповідність Soundex. en.wikipedia.org/wiki/Soundex
Гілберт Ле Бланк

Відповіді:


12

Орієнтовна початкова точка пошуку рядків - відстань Левенштейна . Цей алгоритм підраховує кількість редагувань одного символу (вставлення, видалення та заміна) для зміни одного слова на інше.

Прикладом цього є kitten-> sittingякий має відстань редагування три

  1. k itten -> s itten (замінити 's' на 'k')
  2. sitt e n -> sitt i n (замінити 'i' на 'e')
  3. sittin -> sittin g (в кінці додайте 'g')

У цьому алгоритмі існують різні варіанти, зокрема відстань Дамерау - Левенштейн, яка дозволяє переносити два суміжних символи ("hte" до "the" має відстань DL 1 і відстань Левенштейна 2), і тому часто більше підходить для перевірка орфографії. Інші варіанти існують для додатків, де важливі прогалини (рядки ДНК).

Відстань Левенштейна добре відома і не надто складна для пошуку (мені колись довелося переслідувати її реалізацію як функцію в Oracle - це було набагато швидше, ніж витягувати всі дані і потім запускати сторону коду запиту). Розеттакод має безліч (54) реалізацій відстані Левенштейна (зауважте, що деякі мови мають десь частину бібліотеки струн - якщо ви робите Java, подивіться на apache commons lang ). Wikibooks має 31 реалізацію, і короткий погляд на два не показує однаковий код для тієї самої мови.

Як це працює, це будує матрицю, яка відповідає взаємозв'язку між двома рядками:

 .kitten
.0123456
s1123456
i2212345
t3321234
t4432123
i5543223
n6654332
g7765443

.Рядків і стовпців представляють , що ви можете отримати в цільової рядку по «просто» вставити кожну букву з порожнього рядка. Це не ідеальний випадок, але він існує для виведення алгоритму.

Якщо значення збігається з точкою ('i' == 'i'), значення те саме, що значення діагонально вліво зліва. Якщо дві плями відрізняються ('s'! = 'K'), значення є мінімальним:

  • по діагоналі вліво та вліво + 1 (заміна)
  • безпосередньо над + 1 (вставка)
  • безпосередньо вліво + 1 (видалення)

Значення повернення відстані редагування - це значення в нижньому правому куті матриці.

Якщо слідувати з правого нижнього правого верхнього лівого кута з мінімумом, ви можете побачити зроблені зміни:

 .kitten
.0.   .
s.1   .
i  1  .
t   1 .
t    1.
i.....2
n      2
g......3

Зауважте, що це досить інтенсивний пам'ять. Це може бути зменшено в області пам’яті, не будуючи повну матрицю - весь алгоритм, який піклується, - це підмножина даних, і його можна зменшити з N*Mпростору в 2*max(N,M)простір, просто зберігаючи попередній рядок (і те, що було обчислено за поточним ряд). Проект Code показує, як це можна зробити (з завантаженням коду C #).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.