Алгоритм Ландау-Вишкина (k несовпадений) — различия между версиями
Margarita (обсуждение | вклад) |
Margarita (обсуждение | вклад) |
||
Строка 2: | Строка 2: | ||
Дано число <tex>k > 0</tex> текст <tex>y[1...n]</tex> и образец <tex>x[1...m]</tex>, <tex>m < n</tex>. Требуется найти все подстроки текста длины <tex>m</tex>, с не более чем <tex>k</tex> несовпадающими символами. | Дано число <tex>k > 0</tex> текст <tex>y[1...n]</tex> и образец <tex>x[1...m]</tex>, <tex>m < n</tex>. Требуется найти все подстроки текста длины <tex>m</tex>, с не более чем <tex>k</tex> несовпадающими символами. | ||
− | == | + | ==Алгоритм== |
При анализе текста используется двумерный массив <tex>tm[0...n-m][1...k+1]</tex>, содержащий информацию о несовпадениях текста с образцом. По завершении анализа в его <tex>i</tex>-й строке содержатся позиции в <tex>x</tex> первых <tex>k+1</tex> несовпадений между строками <tex>x[1...m]</tex> и <tex>y[i+1...i+m]</tex>. Таким образом, если <tex>tm[i][v] = s</tex>, то <tex>y[i+s] \neq x[s]</tex>, и это <tex>v</tex>-е несовпадение между <tex>x[1...m]</tex> и <tex>y[i+1...i+m]</tex>, считая слева направо. Если число <tex>d</tex> несовпадений <tex>x[1...m]</tex> с подстрокой <tex>y[i+1...i+m]</tex> меньше <tex>k+1</tex>, то, начиная с <tex>d+1</tex>, элементы <tex>i</tex>-й строки равны значению по умолчанию <tex>m+1</tex>. | При анализе текста используется двумерный массив <tex>tm[0...n-m][1...k+1]</tex>, содержащий информацию о несовпадениях текста с образцом. По завершении анализа в его <tex>i</tex>-й строке содержатся позиции в <tex>x</tex> первых <tex>k+1</tex> несовпадений между строками <tex>x[1...m]</tex> и <tex>y[i+1...i+m]</tex>. Таким образом, если <tex>tm[i][v] = s</tex>, то <tex>y[i+s] \neq x[s]</tex>, и это <tex>v</tex>-е несовпадение между <tex>x[1...m]</tex> и <tex>y[i+1...i+m]</tex>, считая слева направо. Если число <tex>d</tex> несовпадений <tex>x[1...m]</tex> с подстрокой <tex>y[i+1...i+m]</tex> меньше <tex>k+1</tex>, то, начиная с <tex>d+1</tex>, элементы <tex>i</tex>-й строки равны значению по умолчанию <tex>m+1</tex>. | ||
− | [[Файл:algLandauVishkin1.png|thumb|380px|right| | + | [[Файл:algLandauVishkin1.png|thumb|380px|right| В таблицу tm по номеру несовпадения записывается соответстующий индекс образца.]] |
Заметим, если <tex>tm[i][k+1] = m+1</tex>, то подстрока <tex>y[i+1...i+m]</tex> отличается от образца <tex>x</tex> не более, чем на <tex>k</tex> символов, и, таким образом, является решением задачи. | Заметим, если <tex>tm[i][k+1] = m+1</tex>, то подстрока <tex>y[i+1...i+m]</tex> отличается от образца <tex>x</tex> не более, чем на <tex>k</tex> символов, и, таким образом, является решением задачи. | ||
Строка 34: | Строка 34: | ||
==Пример== | ==Пример== | ||
Пусть <tex>x = "tram"</tex>, <tex>y = "thetrippedtrap"</tex>, <tex>k = 2</tex>. | Пусть <tex>x = "tram"</tex>, <tex>y = "thetrippedtrap"</tex>, <tex>k = 2</tex>. | ||
− | + | {| class="wikitable" cellpadding="4" border="1" style="border-collapse: collapse; text-align: center;" | |
+ | |- | ||
+ | | tm || '''1''' || '''2''' || '''3''' || x[1..m] || y[i+1..i+m] | ||
+ | |- | ||
+ | | '''0''' || 2 || 3 || 4 || '''t'''ram || '''t'''het | ||
+ | |- | ||
+ | | '''1''' || 1 || 2 || 3 || tram || hetr | ||
+ | |- | ||
+ | | '''2''' || 1 || 2 || 3 || tram || etri | ||
+ | |- | ||
+ | | '''3''' || 3 || 4 || style="background:#FFCC00"| 5 || '''tr'''am || '''tr'''ip | ||
+ | |- | ||
+ | | '''4''' || 1 || 2 || 3 || tram || ripp | ||
+ | |- | ||
+ | | '''5''' || 1 || 2 || 3 || tram || ippe | ||
+ | |- | ||
+ | | '''6''' || 1 || 2 || 3 || tram || pped | ||
+ | |- | ||
+ | | '''7''' || 1 || 2 || 3 || tram || pedt | ||
+ | |- | ||
+ | | '''8''' || 1 || 2 || 3 || tram || edtr | ||
+ | |- | ||
+ | | '''9''' || 1 || 2 || 3 || tram || dtra | ||
+ | |- | ||
+ | | '''10''' || 4 || style="background:#FFCC00"| 5 || style="background:#FFCC00"| 5 || '''tra'''m || '''tra'''p | ||
+ | |} | ||
//todo pm | //todo pm |
Версия 14:26, 15 июня 2014
Постановка задачи
Дано число
текст и образец , . Требуется найти все подстроки текста длины , с не более чем несовпадающими символами.Алгоритм
При анализе текста используется двумерный массив
, содержащий информацию о несовпадениях текста с образцом. По завершении анализа в его -й строке содержатся позиции в первых несовпадений между строками и . Таким образом, если , то , и это -е несовпадение между и , считая слева направо. Если число несовпадений с подстрокой меньше , то, начиная с , элементы -й строки равны значению по умолчанию .Заметим, если
, то подстрока отличается от образца не более, чем на символов, и, таким образом, является решением задачи.
Затем образец сканируется параллельно с текстом слева на права по одному символу за раз. На итерации
с образцом сравнивается подстрока . - обозначим самую правую позицию в тексте, достигнутую за предыдущие итерации, то есть является максимальным из чисел , где //todo. Если , в присваивается результат работы , которая находит количество несовпадений между и . Если не превышает , вызывается процедура , которая сравнивает подстроки и . Переменная будет рассмотренна ниже.
tm[0...n-m][1...k+1] = m+1 // инициализация r = 0 j = 0 for i = 0 to n - m b = 0 if i < j b = merge(i, r, j) if b < k + 1 r = i extend(i, j, b)
|
и в случае несовпадения
увеличивается и таблица текстовых несовпадений обновляется. Если найдено несовпадений, обработка заканчивается, иначе найдено вхождение образца в подстроке .Пример
Пусть
, , .tm | 1 | 2 | 3 | x[1..m] | y[i+1..i+m] |
0 | 2 | 3 | 4 | tram | thet |
1 | 1 | 2 | 3 | tram | hetr |
2 | 1 | 2 | 3 | tram | etri |
3 | 3 | 4 | 5 | tram | trip |
4 | 1 | 2 | 3 | tram | ripp |
5 | 1 | 2 | 3 | tram | ippe |
6 | 1 | 2 | 3 | tram | pped |
7 | 1 | 2 | 3 | tram | pedt |
8 | 1 | 2 | 3 | tram | edtr |
9 | 1 | 2 | 3 | tram | dtra |
10 | 4 | 5 | 5 | tram | trap |
//todo pm