85(023)
ББК 22.18
О-52
С е р и я о с н о в а н а в 2008 г.
Окулов С. М.
О-52 Алгоритмы обработки строк [Электронный ресурс] /
С. М. Окулов. — 3-е изд. (эл.). — Электрон. текстовые
дан. (1 файл pdf : 258 с.). — М. : БИНОМ. Лаборатория
знаний, 2015. — (Развитие интеллекта школьников). —
Систем. требования: Adobe Reader XI ; экран 10".
ISBN 978-5-9963-2622-8
На материале задачи поиска подстроки в строке, ре-
шению которой посвящены работы многих профессионалов
за последние 20–30 лет, показано, как построить занятия
по информатике, чтобы побудить школьника к творчеству,
развить у него вкус к решению исследовательских проблем.
Для школьников, преподавателей информатики, а также
для студентов, выбравших информатику в качестве основной
специальности. Книга может быть использована как в обыч-
ных школах при проведении факультативных занятий, так
и в образовательных учреждениях с углубленным изучением
информатики и математики.
УДК 519.85(023)
ББК 22.18
Предисловие . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Глава 1. Строки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.1. Основные понятия . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2. Методы предварительного анализа строк . . . . . . . . . 13
Предисловие
Структура книги
Первая глава, с одной стороны, является вводной, а с
другой — дает основы предварительного анализа строк, без
которых понимание многих изложенных далее алгоритмов
невозможно. Но, вероятно, главным в ней следует считать
«очерчивание» одного из основных способов построения эф-
фективных алгоритмов, который заключается в тщатель-
ном анализе исходных данных с целью выявления в них за-
кономерностей, а затем — в использовании этих закономер-
ностей при решении основной задачи.
Во второй главе рассматриваются ставшие уже класси-
кой алгоритмы Д. Кнута – Дж. Морриса – В. Пратта; Р. Бой-
ера – Дж. Мура; Р. Карпа – М. Рабина; Shift–And (Б. Дёмёл-
ки – Р. Беза-Йетс – Г. Гоннет); М. Крочемора и М. Мейна –
Р. Лоренца. Если первые четыре алгоритма посвящены проб-
леме поиска подстроки в строке, то последние два являются
основополагающими в задаче анализа свойств строки (тек-
ста). Во второй главе кратко показано, как использовать аппа-
рат теории автоматов при описании алгоритмов на строках.
Третья глава целиком посвящена деревьям суффик-
сов — структуре данных, в которой фиксируются особен-
ности строки (текста), позволяющие эффективно решать
многочисленные задачи обработки строк. Рассмотрены два
алгоритма — Э. Укконена и Е. Мак-Крейга, однако их рас-
смотрению предшествует анализ простых методов построе-
ния дерева суффиксов, что позволяет сделать изложение
доступным и ясным (с точки зрения автора). На остальные
известные алгоритмы решения этой задачи в данной книге
приводятся только ссылки.
В четвертой главе рассматриваются задачи вычисления
расстояния между строками и нахождения наибольшей об-
щей подпоследовательности двух строк. Анализ первой за-
1)
Кирюхин В. М. Информатика: всероссийские олимпиады. — М.: Просвеще-
ние, 2008. С. 71.
2)
Там же. С. 67.
8 Предисловие
Ñòðîêè
Ïðèìåðû
abc < abcd (n = 3, m = 4); abdef < ada (i = 2, b < d).
Ïðåôèêñ ñòðîêè S, çàêàí÷èâàþùèéñÿ â ïîçèöèè i, —
ýòî ïîäñòðîêà S[1..i].
Ñóôôèêñ ñòðîêè S, íà÷èíàþùèéñÿ â ïîçèöèè i, — ýòî
ïîäñòðîêà S[i..n].
1.1. Îñíîâíûå ïîíÿòèÿ 11
Procedure Solve;
{P, T – ãëîáàëüíûå âåëè÷èíû òèïà String}
Var i,j:Integer;
Begin
For i:=1 To n-m+1 Do Begin
j:=1;
While (j<=m) And (P[j]=T[i+j-1]) Do j:=j+1;
If j=m+1 Then WriteLn('íàéäåíî âõîæäåíèå P â T,
íà÷èíàÿ ñ ïîçèöèè ', i);
End;
End;
Îöåíèì âðåìÿ ðàáîòû ýòîãî àëãîðèòìà â êîëè÷åñòâå îïå-
ðàöèé ñðàâíåíèÿ. Îíî î÷åâèäíî è èìååò çíà÷åíèå O(n·m).
Òàêàÿ îöåíêà äîñòèãàåòñÿ ïðè n – m + 1 ñîâïàäåíèÿõ, ò. å.
êîãäà è P, è T ñîñòîÿò èç îäíîãî ñèìâîëà. Ïðè çíà÷åíèÿõ
m > 103, n > 109 âðåìÿ ðàáîòû òàêîãî àëãîðèèòìà ñòàíîâèò-
ñÿ íåïðèåìëåìûì äëÿ ìíîãèõ ïðèëîæåíèé.
Öåëüþ ñïåöèàëèñòîâ ïî èíôîðìàòèêå çà ïîñëåäíèå 30 ëåò
ÿâëÿåòñÿ ðàçðàáîòêà àëãîðèòìîâ ïîèñêà âõîæäåíèÿ îáðàçöà â
òåêñò (èíîãäà — óäèâèòåëüíûõ è íåîæèäàííûõ, êàê ñêàçêà J),
à òàêæå ðåøåíèå öåëîãî ðÿäà ðîäñòâåííûõ çàäà÷, ñ âðåìåííîé
îöåíêîé ïîðÿäêà O(n + m). Áîëüøèíñòâî ðåçóëüòàòîâ ïðè
ýòîì îñíîâàíî íà ïðåäâàðèòåëüíîì àíàëèçå îáðàçöà èëè òåê-
ñòà (â çàâèñèìîñòè îò çàäà÷è), íàïðàâëåííîì íà âûÿâëåíèå,
åñëè ìîæíî òàê âûðàçèòüñÿ, åãî ñòðóêòóðû, ñ ïîñëåäóþùèì
èñïîëüçîâàíèåì ýòîé èíôîðìàöèè äëÿ ðåøåíèÿ çàäà÷è. Ðàçó-
ìååòñÿ, ñìûñë èìåþò òîëüêî àëãîðèòìû ñ âðåìåííîé îöåíêîé
O(n) èëè O(m). Ñêàæåì, òàêîé àíàëèç P ïîçâîëèë áû ðåøèòü
çàäà÷ó èç ïðèâåäåííîãî íà ðèñ. 1.1 ïðèìåðà íå çà 16 ñäâèãîâ,
à çà ãîðàçäî ìåíüøåå èõ ÷èñëî (íàïðèìåð, 9).
@ Óïðàæíåíèÿ
1. Ñôîðìóëèðóéòå îòëè÷èå ñëåäóþùåé ðåàëèçàöèè ïðî-
ñòîãî àëãîðèòìà ïîèñêà âõîæäåíèÿ P â T îò ðàíåå ïðèâå-
äåííîé.
Procedure Solve;
{P, T – ãëîáàëüíûå âåëè÷èíû òèïà String}
Var i,j:Integer;
Begin
For i:=1 To n-m+1 Do Begin
1.2. Ìåòîäû ïðåäâàðèòåëüíîãî àíàëèçà ñòðîê 13
j:=m;
While (j>=1) And (P[j]=T[i+j-1]) Do j:=j-1;
If j=0 Then WriteLn('íàéäåíî âõîæäåíèå P
â T, íà÷èíàÿ ñ ïîçèöèè ', i);
End;
End;
2. Â ôîðìàëèçîâàííîé çàïèñè àëãîðèòìà ïðîñòîãî ïîèñêà
ñ÷èòàëîñü, ÷òî êàê P, òàê è T èìåþò äëèíû, äîïóñêàþ-
ùèå èñïîëüçîâàíèå òèïà äàííûõ String. Ñíèìèòå ýòî
îãðàíè÷åíèå. Ïðåäïîëîæèòå, íàïðèìåð, ÷òî m = 100, à
n = 10000. Ñîîòâåòñòâåííî èçìåíèòå ðåàëèçàöèþ ìåòî-
äà è îöåíèòå (ýêñïåðèìåíòàëüíî) âðåìÿ åãî ðàáîòû.
Ïðèìå÷àíèå. Äëÿ ýòîãî ïîòðåáóåòñÿ äîïîëíèòåëüíî íà-
ïèñàòü ãåíåðàòîð ñëó÷àéíûõ ñòðîê çàäàííîé äëèíû.
3. Äàíû äâå ñòðîêè — S1 è S2. Îïðåäåëèòå, íàïèñàâ ñîîòâåò-
ñòâóþùóþ ïðîãðàììó, ìîæíî ëè îäíó (ëþáóþ) èç ýòèõ
ñòðîê ïîëó÷èòü öèêëè÷åñêèì ñäâèãîì äðóãîé ñòðîêè.
Òàáëèöà 1.1
¹ S Br
1 aaaaaa 0, 1, 2, 3, 4, 5
2 abcdef 0, 0, 0, 0, 0, 0
3 abaababaabaab 0, 0, 1, 1, 2, 3, 2, 3, 4, 5, 6, 4, 5
4 abcabcabcabc=(abc)4 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
5 abcabdabcabeabcabd 0, 0, 0, 1, 2, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4,
abcabc 5, 6, 7, 8, 9, 10, 11, 3
Òàáëèöà 1.2
I Äëèíà ãðàíåé
24 3, 0
23 11, 5, 2, 0
22 10, 4, 1, 0
21 9, 3, 0
20 8, 2, 0
... ...
Ïðèìåð
 òàáë. 1.3 ïîêàçàíà ñòðîêà S è ìàññèâû ãðàíåé ïðåôèê-
ñîâ br è ñóôôèêñîâ bw äëÿ íåå.
Òàáëèöà 1.3
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
S a b a a b a b a a b a a b a b a a b a b a
br 0 0 1 1 2 3 2 3 4 5 6 4 5 6 7 8 9 10 11 7 8
bw 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 3 2 1 0 0
i 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
S a b c a b d a b c a b e a b c a b d a b c a b c
bl 0 0 0 2 0 0 5 0 0 2 0 0 11 0 0 2 0 0 5 0 0 3 0 0
r 0 0 0 5 5 0 11 11 11 11 11 0 23 23 23 23 23 23 23 23 23 24 24 24
l 0 0 0 4 4 0 7 7 7 10 10 0 13 13 13 13 13 13 19 19 19 22 22 22
@ Óïðàæíåíèÿ
1. Â àëãîðèòìå íàõîæäåíèÿ íàèáîëüøåé ãðàíè ñòðîêè S ñ
âðåìåííîé ñëîæíîñòüþ O(n2) ïîèñê íà÷èíàëñÿ ñ íàè-
ìåíüøåãî âîçìîæíîãî çíà÷åíèÿ ãðàíè. Èçìåíèòå ýòîò
àëãîðèòì òàê, ÷òîáû ïîèñê íà÷èíàëñÿ ñ ìàêñèìàëüíî
âîçìîæíîãî çíà÷åíèÿ è ïðè íàõîæäåíèè ïåðâîãî ñîâïà-
äåíèÿ çàâåðøàë ðàáîòó.
2. Âû÷èñëèòå ìàññèâ ãðàíåé ïðåôèêñîâ è ñóôôèêñîâ äëÿ
ñòðîê:
l ab;
l abba;
l abbabaab;
26 Ãëàâà 1. Ñòðîêè
l abbabaabbaababba;
l abbabaabbaababbabaababbaabbabaab;
l abcab;
l abcabacabcbacbcacbabcabacabcb;
l abcabacabcbacbcacbabcabacabcbabcabacbcacbabc
abacabcbacbcacbacabcbabcabacbcacbacabcbacbca
cbabcabacbcacbacabcbabcabacabcbacbcacbabcaba
cabcbabcabacbcacbabcabacabcbacbcacbacabcb;
l aba;
l abaab;
l abaabaab;
l abaababaabaab;
l abaababaabaababaabaab;
l abaababaabaababaabaababaababaabaab.
3. Ðàçðàáîòàéòå ïðîãðàììó ïîèñêà P â T ñ èñïîëüçîâàíèåì
ìåòîäà âû÷èñëåíèÿ ìàññèâà ãðàíåé ïðåôèêñîâ. Ýêñïå-
ðèìåíòàëüíî îöåíèòå âðåìÿ åå ðàáîòû äëÿ ïðåäåëüíî
áîëüøèõ ñòðîê.
4. Ðàçðàáîòàéòå ïðîãðàììó ïîèñêà P â T ñ èñïîëüçîâàíèåì
ìåòîäà âû÷èñëåíèÿ ìàññèâà áëîêîâ. Ýêñïåðèìåíòàëüíî
îöåíèòå âðåìÿ åå ðàáîòû äëÿ ïðåäåëüíî áîëüøèõ ñòðîê.
5. Âîçüìèòå ïðîèçâîëüíóþ ñòðîêó S. «Ïåðåâåðíèòå» åå,
ò. å. ïîäâåðãíèòå ïðåîáðàçîâàíèþ:
S’:=’’;
For i:= n DownTo 1 Do S’:=S’+S[i]; {n=Length(S)}
Ìåòîäè÷åñêèé êîììåíòàðèé
Ïðè ðàññìîòðåíèè çàäà÷è òî÷íîãî ïîèñêà îáðàçöà â èçâåñò-
íûõ àâòîðó êíèãàõ1) íà ðóññêîì ÿçûêå îáû÷íî èñïîëüçóåòñÿ
îäèí èç ìåòîäîâ ïðåäâàðèòåëüíîãî àíàëèçà îáðàçöà. Ðàññìîò-
ðåíèå îáîèõ ìåòîäîâ è èõ èñïîëüçîâàíèå ïðè îáñóæäåíèè îñî-
áåííîñòåé àëãîðèòìîâ íå íàðóøàåò öåëîñòíîñòè èçëîæåíèÿ;
íàîáîðîò, òàêîé ïîäõîä ïîçâîëÿåò â î÷åðåäíîé ðàç ïîä÷åðê-
íóòü îñíîâíîå ïîëîæåíèå ïðîöåññà ïîëó÷åíèÿ ýôôåêòèâíûõ
àëãîðèòìîâ — «èç íè÷åãî íå ðîæäàåòñÿ íå÷òî». Äðóãèìè ñëî-
âàìè, äëÿ äîñòèæåíèÿ ðåçóëüòàòà òðåáóåòñÿ âûÿâèòü çàêîíî-
ìåðíîñòè â èñõîäíûõ äàííûõ è ïðåäñòàâèòü èõ â íîâûõ ñòðóê-
òóðàõ äàííûõ, èñïîëüçîâàíèå êîòîðûõ ïðèâîäèò ê ýôôåêòó
(ïî çàòðàòàì âðåìåíè ëèáî ïî ðàñõîäîâàíèþ ðåñóðñà ïàìÿòè)
ïðè ðåàëèçàöèè îñíîâíîé îáðàáîòêè (ëîãèêè àëãîðèòìà).
1)
Ãàñôèëä Ä. Ñòðîêè, äåðåâüÿ è ïîñëåäîâàòåëüíîñòè â àëãîðèòìàõ: Èíôîðìà-
òèêà è âû÷èñëèòåëüíàÿ áèîëîãèÿ / ïåð. ñ àíãë. È. Â. Ðîìàíîâñêîãî. — ÑÏá.:
Íåâñêèé Äèàëåêò; ÁÕÂ-Ïåòåðáóðã, 2003; Ñìèò Á. Ìåòîäû è àëãîðèòìû âû-
÷èñëåíèé íà ñòðîêàõ. — Ì.: ÎÎÎ «È. Ä. Âèëüÿìñ», 2005.
Ãëàâà 2
Òàáëèöà 2.1
i 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
P a b c a e a b c a b c a
br 0 0 0 1 0 1 2 3 4 2 3 4
a b c a e a b c a b c a
Òàáëèöà 2.2
i 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
T a b a b c x a b d a b c x a b c x a b c d e
P a b c x a b c d e
a b c x a b c d e
a b c x a b c d e
a b c x a b c d e
a b c x a b c d e
a b c x a b c d e
Ïðèìåð 1
Ïóñòü T = aaaaaaaaaaaa è P = aaaaa. Î÷åâèäíî, ÷òî P
âõîäèò â T (n – m + 1) = (12 – 5 + 1) = 8 ðàç. Ïîäñ÷èòàåì
êîëè÷åñòâî ñðàâíåíèé. Ïðè ïðîñòîì ìåòîäå ìû èìååì
(n – m + 1) · m = 40 ñðàâíåíèé. Ìàññèâ ãðàíåé br äëÿ P ðàâåí
(0, 1, 2, 3, 4). Ñõåìà ïîèñêà âõîæäåíèé ïî àëãîðèòìó Ä. Êíó-
òà – Äæ. Ìîððèñà – Â. Ïðàòòà ïîêàçàíà â òàáë. 2.3.
Ïîñëå íàõîæäåíèÿ ïåðâîãî âõîæäåíèÿ âû÷èñëÿåì çíà-
÷åíèå ñäâèãà. Îíî ðàâíî (5–br[5]) = (5–4) = 1. Äðóãèìè ñëî-
âàìè, ìû ñäâèãàåì ïîäñòðîêó ïðè îáíàðóæåíèè êàæäîãî
âõîæäåíèÿ íà îäíó ïîçèöèþ. Íî ñðàâíèâàåì ìû ïîñëå ñäâè-
ãîâ òîëüêî ïîñëåäíèé ñèìâîë P[5] ñ î÷åðåäíûì ñèìâîëîì T:
P[5] ñ T[6]; P[5] ñ T[7]; P[5] ñ T[8] è ò. ä. Òàêèì îáðàçîì, äëÿ
ïîèñêà âñåõ âõîæäåíèé òðåáóåòñÿ ëèøü n ñðàâíåíèé, â äàí-
íîì ñëó÷àå — 12, à íå 40.
2.1. Àëãîðèòì Ä. Êíóòà – Äæ. Ìîððèñà – Â. Ïðàòòà 31
Òàáëèöà 2.3
i 1 2 3 4 5 6 7 8 9 10 11 12
T a a a a a a a a a a a a
P a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
Ïðèìåð 2
Ïóñòü T = aaaaaaaaaaaa è P = aaaab. Êàê íåòðóäíî âè-
äåòü, P íå âõîäèò â T. Ïðîñòûì àëãîðèòìîì ýòîò ôàêò óñòà-
íàâëèâàåòñÿ çà 40 ñðàâíåíèé. Ìàññèâ ãðàíåé äëÿ P ðàâåí (0,
1, 2, 3, 0). Ñõåìà ïîèñêà âõîæäåíèÿ P â T ïî àëãîðèòìó
Ä. Êíóòà – Äæ. Ìîððèñà – Â. Ïðàòòà ïðèâåäåíà â òàáë. 2.4.
Òàáëèöà 2.4
i 1 2 3 4 5 6 7 8 9 10 11 12
T a a a a a a a a a a a a
P a a a a b
a a a a b
a a a a b
a a a a b
a a a a b
a a a a b
a a a a b
a a a a b
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
S a b c x a b c d e
br 0 0 0 0 1 2 3 0 0
brs 0 0 0 0 0 0 3 0 0
S a b a a b a b a a b a a b
br 0 0 1 1 2 3 2 3 4 5 6 4 5
brs 0 0 1 0 0 3 0 1 0 0 6 0 5
S a b a a b a b a a b a a b a b a a b a b a
br 0 0 1 1 2 3 2 3 4 5 6 4 5 6 7 8 9 10 11 7 8
brs 0 0 1 0 0 3 0 1 0 0 6 0 0 3 0 1 0 0 11 0 8
@ Óïðàæíåíèÿ
1. Âûïîëíèòå òðàññèðîâêó àëãîðèòìà Ä. Êíóòà – Äæ. Ìîð-
ðèñà – Â. Ïðàòòà ñ èñïîëüçîâàíèåì êàê ìàññèâà ãðàíåé
br, òàê è ìàññèâà brs äëÿ ñëåäóþùèõ ïðèìåðîâ:
l T=abbabaabbaababba, P=abbab;
l T=abcabdabcabeabcabdabcabc, P=abda;
l T=abcabdabcabcabcabd, P=abcabc;
l T=abcabcabdabcabcabcb, P=abcabcabc.
2.1. Àëãîðèòì Ä. Êíóòà – Äæ. Ìîððèñà – Â. Ïðàòòà 35
Òàáëèöà 2.6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
T a x b c f a b a x b a d a b a x a x a a d
1 P a b a x a
2 a b a x a
3 a b a x a
4 a b a x a
5 a b a x a
6 a b a x a
7 a b a x a
8 a b a x a
Òàáëèöà 2.7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
T a b a b c x c d e d e a x a a b c x a b c d e
1 P a b c x a b c d e
2 a b c x a b c d e
3 a b c x a b c d e
4 a b c x a b c d e
5 a b c x a b c d e
6 a b c x a b c d e
Ïðèìåð
Ïóñòü P = abcdabdccbad. Äâóìåðíûé ìàññèâ bs
(òàáë. 2.8) ñîäåðæèò äàííûå î áëèæàéøèõ ëåâûõ âõîæäåíè-
ÿõ ñèìâîëîâ â îáðàçåö. Òàê, P[12] = d, ïðè÷åì ñëåâà â P ñèì-
âîë d ïîâòîðÿåòñÿ íà 7-ì ìåñòå.
40 Ãëàâà 2. Êëàññè÷åñêèå àëãîðèòìû îáðàáîòêè ñòðîê
Òàáëèöà 2.8
1 2 3 4 5 6 7 8 9 10 11 12
a 0 1 5
b 0 2 6
c 0 3 8
d 0 4 7
...
Òàáëèöà 2.9
1 2 3 4
a 11 5 1 0
b 10 6 2 0
c 9 8 3 0
d 12 7 4 0
Ïðèìåð
Ïóñòü T = abaabaabaababaabaaba, à P = abaaba. Â
òàáë. 2.10 ïîêàçàíû çíà÷åíèÿ ñäâèãîâ ïðè ïîèñêå âõîæäå-
íèé P â T.
Ïðè ïåðâîì ïðèêëàäûâàíèè P ñîâïàëî ñ ïîäñòðîêîé èç T.
Ñäâèã íà îäíó ïîçèöèþ íåðàöèîíàëåí, åñëè ñôîðìèðîâàí
ìàññèâ ãðàíåé (br, ñì. ï. 1.2.1) äëÿ P, — â äàííîì ïðèìåðå
br = (0, 0, 1, 1, 2, 3). Ïðàâäà, â äàííîì ñëó÷àå äîñòàòî÷íî
òîëüêî çíà÷åíèÿ br[m], êîòîðîå ãîâîðèò î òîì, ÷òî ó P åñòü
ñóôôèêñ ýòîé äëèíû, ñîâïàäàþùèé ñ ñîáñòâåííûì ïðåôèê-
42 Ãëàâà 2. Êëàññè÷åñêèå àëãîðèòìû îáðàáîòêè ñòðîê
Òàáëèöà 2.10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
T a b a a b a a b a a b a b a a b a a b a
1 P a b a a b a
2 a b a a b a
3 a b a a b a
4 a b a a b a
5 a b a a b a
6 a b a a b a
7 a b a a b a
Procedure BadSymbolJump;
Var i,j,jump:Integer;
Begin
i:=1;
jump:=1;
While i<=(n-m+1) Do Begin
j:=m;
While (j>=jump) And (P[j]=T[i+j-1]) Do j:=j-1;
If j=jump-1 Then Begin
WriteLn('îáðàçåö ',P,' âõîäèò â ',
T, ' ñ ïîçèöèè ',i);
i:=i+br[m];
jump:=m-br[m]+1;
{Ïðè íîâîì ïðèêëàäûâàíèè ñðàâíèâàåì P è T
òîëüêî äî ýòîé ïîçèöèè}
End
Else Begin
i:=i+Max(1,j-bs[t[i+j-1]]);
jump:=1;
{Ïîêà íàì íåèçâåñòíî, êàê ðàáîòàòü
ñ ïåðåìåííîé jump â ýòîì ñëó÷àå}
End;
End;
End;
Òàáëèöà 2.11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
P a b a b a a b b a a b a b b a
bw 1 2 1 2 1 4 3 2 1 1 2 1 0 0 0
bwt 1 2 0 2 0 4 0 0 0 1 2 0 0 0 0
pbwt 0 0 0 0 0 0 0 0 0 0 0 6 0 11 10
@ Óïðàæíåíèÿ
1. Ðàçðàáîòàéòå ïðîãðàììó ïîèñêà P â T òîëüêî ñ èñïîëüçî-
âàíèåì «ïðàâèëà ïëîõîãî ñèìâîëà» (ðàññìîòðèòå êàê
ïðîñòîé ñëó÷àé, òàê è óëó÷øåííûé). Îöåíèòå âðåìÿ åå
ðàáîòû íà ðàçëè÷íûõ òåñòîâûõ ïðèìåðàõ, âêëþ÷àÿ ñëó-
÷àé, êîãäà P = am, T = an (m < n). Ñðàâíèòå âðåìÿ ðàáîòû
ýòîé ïðîãðàììû ñ âðåìåííûìè õàðàêòåðèñòèêàìè îáû÷-
íîãî àëãîðèòìà ïîèñêà îáðàçöà â òåêñòå.
2. Èçìåíèòå ðåøåíèå óïðàæíåíèÿ 1 òàê, ÷òîáû ïðè íà-
õîæäåíèè P â T ñäâèã P îòíîñèòåëüíî T îñóùåñòâëÿëñÿ
íå íà îäíó ïîçèöèþ, à íà çíà÷åíèå, îïðåäåëÿåìîå ìàêñè-
ìàëüíîé äëèíîé ïðåôèêñà P, ñîâïàäàþùåãî ñ ñóôôèê-
ñîì P.
2.2. Àëãîðèòì Ð. Áîéåðà – Äæ. Ìóðà 51
End
Else Begin
If pbwt[j+1]=0 Then v:=m–brsuf[j+1]
Else v:=j+1–pbwt[j+1];
q:=Max(v,j–bs[t[i+j-1]]);
i:=i+q;
If q=m–brsuf[j+1] Then jump:=q
Else jump:=1;
End;
End;
End;
Ïðèìåð
Ð = 10101, m = 5 è H(P) = 1 · 2 4 + 0 · 2 3 + 1 · 2 2 + 0 · 2 1 +
+ 1 · 20 = 21. Åñëè Ò = 1011010101, r = 2, òî H(T2) =
= 0 · 24 + 1 · 23 + 1 · 22 + 0 · 21 + 1 · 20 = 13, à ïðè r = 6
çíà÷åíèå H(T6) = 21. Âûâîä: îáðàçåö P âõîäèò â T ñ øåñòîé
ïîçèöèè (è ñ òðåòüåé).
Òàêèì îáðàçîì, çàäà÷à ïîèñêà âõîæäåíèÿ P â T çäåñü
ôàêòè÷åñêè ñâåäåíà ê âû÷èñëèòåëüíîé çàäà÷å, â êîòîðîé
ñðàâíèâàþòñÿ äâà ÷èñëà H(P) è H(Tr). Íî îïðåäåëåíèå Tr
äëÿ êàæäîãî çíà÷åíèÿ r — òðóäîåìêàÿ çàäà÷à, à êðîìå òîãî,
ñòåïåíè äâîéêè áûñòðî âîçðàñòàþò, ïîýòîìó ïðåîáðàçîâà-
íèå H äëÿ ðåàëüíûõ îáðàçöîâ P ñòàíîâèòñÿ ìàëîýôôåêòèâ-
íûì.
Ðàçâèòèåì ýòîé èäåè — ïðåîáðàçîâàíèÿ ñòðîêè â ÷èñ-
ëî — ñòàëî èñïîëüçîâàíèå îäíîãî èç êëàññè÷åñêèõ ðàçäåëîâ
òåîðèè ÷èñåë, à èìåííî ìîäóëüíîé àðèôìåòèêè. ( ïðèí-
öèïå, è êîìïüþòåðíîå âûïîëíåíèå àðèôìåòè÷åñêèõ îïåðà-
öèé — ýòî âû÷èñëåíèÿ ïî ìîäóëþ ìàêñèìàëüíî äîïóñòèìî-
ãî ÷èñëà â èíòåðâàëå, îïðåäåëåííîì òèïîì äàííûõ.) Ïðè
ýòîì âìåñòî ðàáîòû ñî ñëèøêîì áîëüøèìè ÷èñëàìè H(P) è
H(Tr) ïðåäëàãàåòñÿ âûïîëíÿòü äåéñòâèÿ ñ îñòàòêàìè ïî ìî-
äóëþ íåêîòîðîãî ÷èñëà q (îòíîñèòåëüíî íåáîëüøîãî, ÷òî ïî-
çâîëÿåò èñïîëüçîâàòü ìàëîå êîëè÷åñòâî áèòîâ). Íî â ýòîì
ñëó÷àå âîçíèêàåò äðóãàÿ ïðîáëåìà: ðàçëè÷íûå ÷èñëà ìîãóò
èìåòü îäèí è òîò æå îñòàòîê, ÷òî íåèçáåæíî ïðèâîäèò ê
ëîæíûì ñîâïàäåíèÿì P è T. Ïîýòîìó ñëåäóåò âûáèðàòü q
òàê, ÷òîáû âåðîÿòíîñòü ëîæíîãî ñîâïàäåíèÿ áûëà ìèíè-
ìàëüíîé. Èòàê, H(P) ïåðåâîäèòñÿ â Hq(P) ïóòåì íàõîæäå-
íèÿ H(P) Mod q è Hq(Tr) = H(Tr) Mod q. Îäíàêî òàêàÿ ïîñëå-
äîâàòåëüíîñòü äåéñòâèé, êàê âû÷èñëåíèå H(P) è H(Tr), à çà-
òåì íàõîæäåíèå îñòàòêîâ ïî ìîäóëþ q, åùå íå ðåøàåò
ïðîáëåìû, èáî ïðîìåæóòî÷íûå ðåçóëüòàòû îñòàþòñÿ ïðåæ-
íèìè (áîëüøèìè), à íå â äèàïàçîíå îò 0 äî q – 1. Êàê æå
áûòü? Ðàññìîòðèì ïðîñòîé ïðèìåð.
Ïðèìåð
Ïóñòü q = 7. Âû÷èñëèì 25 Mod 7 = 32 Mod 7 = 4. Ýòî ïðÿ-
ìîå âû÷èñëåíèå. À òåïåðü âû÷èñëèì ((((2 · 2 Mod 7 · 2) Mod
7) · 2) Mod 7 · 2)=4, ò. å. áóäåì âûïîëíÿòü îïåðàöèþ äàëü-
íåéøåãî âîçâåäåíèÿ â ñòåïåíü íàä îñòàòêîì ïðåäûäóùåãî
54 Ãëàâà 2. Êëàññè÷åñêèå àëãîðèòìû îáðàáîòêè ñòðîê
Ïðèìåð
Ïóñòü m = 100, à n = 2000, òîãäà I = 102 · (2 · 103)2 =
= 4 · 108 < 4 · (103)2.7 = 22 · (210)2.7 = 229 < 232. Ïîëó÷àåì,
÷òî 32 áèòîâ äîñòàòî÷íî äëÿ ïðåäñòàâëåíèÿ ïðîñòîãî ÷èñëà q,
ïðè÷åì ìîäóëüíàÿ àðèôìåòèêà áóäåò ýôôåêòèâíî ðàáîòàòü,
à âåðîÿòíîñòü ëîæíîãî ñîâïàäåíèÿ íå áóäåò ïðåâîñõîäèòü
2.53/2000 < 0,001265.
Èòàê, àëãîðèòì Ð. Êàðïà – Ì. Ðàáèíà èìååò âðåìåííóþ
îöåíêó O(n). Íà ñòàäèè ïðåäâàðèòåëüíîé îáðàáîòêè ñëåäóåò
âûáðàòü ïðîñòîå ÷èñëî q, íå ïðåâîñõîäÿùåå ïîëîæèòåëüíî-
ãî öåëîãî I, è âû÷èñëèòü H(P). Äàëüíåéøèå äåéñòâèÿ ñâî-
äÿòñÿ ê ïîñëåäîâàòåëüíîìó âû÷èñëåíèþ H(Tr) è åãî ñðàâíå-
íèþ ñ H(P). Èç-çà âîçìîæíîñòè ëîæíîãî ñîâïàäåíèÿ ïðè ðà-
âåíñòâå H(P) è H(Tr) ìîæíî îðãàíèçîâàòü ïîáèòîâîå
ñðàâíåíèå ýòîé ïîäñòðîêè T ñ P.
@ Óïðàæíåíèÿ
1. Ïðè çàäàííîì m (íàïðèìåð, 100) îïðåäåëèòå ìèíèìàëü-
íî âîçìîæíîå çíà÷åíèå n, ïðè êîòîðîì 32 ðàçðÿäîâ íå
áóäåò õâàòàòü äëÿ ïðåäñòàâëåíèÿ I.
1)
Ãàñôèëä Ä. Ñòðîêè, äåðåâüÿ è ïîñëåäîâàòåëüíîñòè â àëãîðèòìàõ: Èíôîðìà-
òèêà è âû÷èñëèòåëüíàÿ áèîëîãèÿ. — ÑÏá.: Íåâñêèé Äèàëåêò; ÁÕ–Ïåòåð-
áóðã, 2003. Ñ. 112.
2.4. Àëãîðèòì Shift-And 57
Òàáëèöà 2.12
Cèìâîë Ñèìâîë
R a ñ a ñ d
T¯ P ®
Íîìåð Íîìåð
ñèìâîëà ñèìâîëà 0 1 2 3 4 5
T¯ P®
1 a 1 1 0 0 0 0
2 c 1 0 1 0 0 0
3 a 1 1 0 1 0 0
4 c 1 0 1 0 1 0
5 d 1 0 0 0 0 1
6 f 1 0 0 0 0 0
7 a 1 1 0 0 0 0
8 f 1 0 0 0 0 0
9 a 1 1 0 0 0 0
10 c 1 0 1 0 0 0
11 a 1 1 0 1 0 0
12 c 1 0 1 0 1 0
13 d 1 0 0 0 0 1
14 f 1 0 0 0 0 0
Òàáëèöà 2.13
V a c a ñ d
a 1 0 1 0 0
c 0 1 0 1 0
d 0 0 0 0 1
Òàáëèöà 2.14
R0 Ñèìâîë Ñèìâîë
a c a c d
T¯ P®
Íîìåð Íîìåð
ñèìâîëà ñèìâîëà 0 1 2 3 4 5
T¯ P®
1 a 1 1 0 0 0 0
2 c 1 0 1 0 0 0
3 a 1 1 0 1 0 0
4 c 1 0 1 0 1 0
5 a 1 1 0 1 0 0
6 f 1 0 0 0 0 0
7 a 1 1 0 0 0 0
8 c 1 0 1 0 0 0
9 a 1 1 0 1 0 0
10 c 1 0 1 0 1 0
11 d 1 0 0 0 0 1
12 a 1 1 0 0 0 0
64 Ãëàâà 2. Êëàññè÷åñêèå àëãîðèòìû îáðàáîòêè ñòðîê
Òàáëèöà 2.15
R1 Ñèìâîë Ñèìâîë
a c a c d
T¯ P®
Íîìåð Íîìåð
ñèìâîëà ñèìâîëà 0 1 2 3 4 5
T¯ P®
1 a 1 1 0 0 0 0
2 c 1 1 1 0 0 0
3 a 1 1 0 1 0 0
4 c 1 1 1 0 1 0
5 a 1 1 0 1 0 1
6 f 1 1 1 0 1 0
7 a 1 1 0 1 0 0
8 c 1 1 1 0 1 0
9 a 1 1 0 1 0 0
10 c 1 1 1 0 1 0
11 d 1 1 0 1 0 1
12 a 1 1 0 0 0 0
Òàáëèöà 2.16
Ñèì- Íîìåð R0 R1 R2 R3
âîë ñèìâîëà
a 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0
b 2 0 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0
c 3 0 0 1 0 1 0 1 0 1 1 1 0 1 1 1 0
e 4 0 0 0 0 1 0 0 1 1 1 0 1 1 1 1 1
a 5 1 0 0 0 1 0 0 0 1 1 0 0 1 1 1 0
b 6 0 1 0 0 1 1 0 0 1 1 0 0 1 1 1 0
f 7 0 0 0 0 1 0 1 0 1 1 1 0 1 1 1 0
e 8 0 0 0 0 1 0 0 0 1 1 0 1 1 1 1 1
a 9 1 0 0 0 1 0 0 0 1 1 0 0 1 1 1 0
k 10 0 0 0 0 1 1 0 0 1 1 0 0 1 1 1 0
r 11 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 0
t 12 0 0 0 0 1 0 0 0 1 1 0 0 1 1 1 1
@ Óïðàæíåíèÿ
1. Âûïîëíèòå òðàññèðîâêó àëãîðèòìà Shift-And, íàïðè-
ìåð, ïðè P = abac è T = aabañcababacab.
2. Ýêñïåðèìåíòàëüíî ñðàâíèòå âðåìÿ ðàáîòû ïðîñòîãî àë-
ãîðèòìà ïîèñêà îáðàçöà â òåêñòå è àëãîðèòìà Shift-And.
3. Â àëãîðèòìå Shift-And íà âõîæäåíèå ïðåôèêñîâ óêàçû-
âàåò 1. Èçìåíèì óñëîâèå: ïóñòü íà âõîæäåíèå ïðåôèêñà
óêàçûâàåò çíà÷åíèå 0. Òîãäà ýòî óæå áóäåò àëãîðèòì íå
Shift-And, à «Shift-Or». Ðàçáåðèòå ïðèâåäåííûé íèæå
ëèñòèíã è ïðîâåðüòå åãî ðàáîòîñïîñîáíîñòü.
Procedure SeachShiftOr(P,T:String);
Var V:Array [Chr(0)..Chr(255)] Of LongInt;
n,m,i:Byte;
h,R: LongInt;
j:Ñhar;
68 Ãëàâà 2. Êëàññè÷åñêèå àëãîðèòìû îáðàáîòêè ñòðîê
Begin
n:=Length(T);
m:=Length(P);
h:=1 ShL m-1;
For j:= Chr(0) To Chr(255) Do V[j]:=h;
For i:=1 To m Do V[P[i]]:=V[P[i]] And
(Not(1 ShL (m-i)));
R:=h;
For i:=1 To n Do Begin
R:=(R ShR 1) Or V[T[i]];
If R And 1 = 0 Then WriteLn(i-m+1);
End;
End;
Ïðèìå÷àíèå.  îñíîâíîì öèêëå íà îäíó áèòîâóþ îïåðà-
öèþ çäåñü ñòàëî ìåíüøå, òàê êàê äîïîëíåíèå åäèíèöåé
ïðè ñäâèãå íå òðåáóåòñÿ. (Îáúÿñíèòå ïî÷åìó.)
4. Ðàçðàáîòàéòå ìåòîä «ðåãèñòðîíåçàâèñèìîãî» (ò. å. âíå
çàâèñèìîñòè îò ðåãèñòðà áóêâ) ïîèñêà îáðàçöà â òåêñòå.
Ïðèìå÷àíèå. Äëÿ ýòîãî äîñòàòî÷íî äëÿ îäíèõ è òåõ æå
áóêâ ðàçíîãî ðåãèñòðà ïîñòðîèòü îäèíàêîâûå õàðàêòå-
ðèñòè÷åñêèå âåêòîðû. Îñíîâíàÿ æå ÷àñòü àëãîðèòìà
Shift-And îñòàíåòñÿ áåç èçìåíåíèé.
5. Èçâåñòíî, ÷òî â òåêñòå áåç öèôð íåêîòîðûå áóêâû áûëè
çàìåíåíû öèôðàìè. Íàéäèòå âõîæäåíèå îáðàçöà â òà-
êîì «èñïîð÷åííîì» òåêñòå.
Ïðèìå÷àíèå. Äëÿ ýòîãî ñëåäóåò õàðàêòåðèñòè÷åñêèå
âåêòîðû öèôð ñäåëàòü åäèíè÷íûìè: ýòî áóäåò îçíà÷àòü,
÷òî öèôðà ìîæåò ïîÿâèòüñÿ â ëþáîé ïîçèöèè ñëîâà.
6. Àâòîìîáèëüíûå íîìåðà èìåþò âèä: «áóêâà, òðè öèôðû,
äâå áóêâû», íàïðèìåð «ì815òê». Íàéäèòå â òåêñòå âñå
òàêèå àâòîìîáèëüíûå íîìåðà.
Ïðèìå÷àíèå. Õàðàêòåðèñòè÷åñêèå âåêòîðû äëÿ âñåõ
áóêâ íóæíî ïîëîæèòü ðàâíûìè 100011, äëÿ öèôð —
011100, à äëÿ âñåõ îñòàëüíûõ ñèìâîëîâ — íóëåâûìè.
7. Â òåêñòå íåêîòîðûå áóêâû, íàïðèìåð o, áûëè çàìåíåíû
áóêâîé a. Êàê íàéòè ñëîâî â òàêîì «èñïîð÷åííîì» òåê-
ñòå?
Ïðèìå÷àíèå. Íóæíî ñôîðìèðîâàòü õàðàêòåðèñòè÷åñ-
êèå âåêòîðû äëÿ âñåõ ñèìâîëîâ àëôàâèòà, à çàòåì ñêîð-
2.4. Àëãîðèòì Shift-And 69
Ïðèìåð
A = {a, b}, Q = {q0, q1, q2}, E = {q2}. Ôóíêöèÿ F ïðèâåäå-
íà â òàáë. 2.17.
74 Ãëàâà 2. Êëàññè÷åñêèå àëãîðèòìû îáðàáîòêè ñòðîê
Òàáëèöà 2.17
F a b
q0 q1 q0
q1 q1 q2
q2 q1 q2
@ Óïðàæíåíèÿ
1. Äëÿ êàæäîãî èç ïðèâåäåííûõ íà ðèñ. 2.8 àâòîìàòîâ (äè-
àãðàìì ñîñòîÿíèé) îïðåäåëèòå ìíîæåñòâî äîïóñòèìûõ
ñëîâ.
Ïðèìå÷àíèå. Íà÷àëüíîå ñîñòîÿíèå — q0, êîíå÷íûå ñî-
ñòîÿíèÿ âûäåëåíû ñåðûì öâåòîì.
1)
Àíäåðñîí Ä. Äèñêðåòíàÿ ìàòåìàòèêà è êîìáèíàòîðèêà. — Ì.: Èçäàòåëüñêèé
äîì «Âèëüÿìñ», 2003. Ñ. 736–737.
76 Ãëàâà 2. Êëàññè÷åñêèå àëãîðèòìû îáðàáîòêè ñòðîê
Òàáëèöà 2.18
Ñîñòîÿíèå
F
0 1 2 3 4 5 6 7 8 9
a 1 2 2 1 5 2 1 8 9 2
Âõîäíîé
b 0 0 3 4 0 6 0 0 0 3
ñèìâîë
c 0 0 0 0 0 0 7 0 0 0
Ñîñòîÿíèå
F
0 1 2 3 4 5 6 7 8
Âõîäíîé a 1 1 3 4 1 6 4 8 4
ñèìâîë b 0 2 0 2 5 0 7 0 2
Òàáëèöà 2.20
T a b a a a b a b a a b a b a a
q 0 1 2 3 4 1 2 3 2 3 4 5 6 7 8 4
Procedure Automat;
Var j:Integer;
q:Char;
Begin
For qÎA Do
If P[1]=q Then F[0,q]:=1 Else F[0,q]:=0;
For j:=1 To m Do
For qÎA Do
{Öèêë ïî ñèìâîëàì àëôàâèòà A}
If P[j+1]=q Then F[j,q]:=j+1
Else F[j,q]:=F[br[j],q];
End;
Ïðèìå÷àíèå. Ïðåäïîëàãàåòñÿ, ÷òî ê êîíöó P ïðèïèñàí
ñèìâîë, îòñóòñòâóþùèé â A, íàïðèìåð $.
@ Óïðàæíåíèÿ
1. Ïðèâåäèòå ïðèìåð îáðàçöà è ïîñòðîéòå äëÿ íåãî àâòîìàò
ðàñïîçíàâàíèÿ.
2. Ïîñòðîéòå àâòîìàò ðàñïîçíàâàíèÿ îáðàçöà â òåêñòå íà
îñíîâå ìàññèâà ãðàíåé ñóôôèêñîâ.
3. Ñêîíñòðóèðóéòå àâòîìàò (åñëè ýòî âîçìîæíî) äëÿ ðàñ-
ïîçíàâàíèÿ îáðàçöà â òåêñòå ñ èñïîëüçîâàíèåì äàííûõ,
ïðåäñòàâëåííûõ â ìàññèâå áëîêîâ.
Ïðèìåðû
1) S = abcabcabcabc; z = 9; Þ r = 4; U = abc;
2) S = abab; z = 2; Þ r = 2; U = ab;
3) S = bbbbb; z = 4; Þ r = 5; U = b;
4) S = ababa; z = 3; Þ r = 5/2, ñòðîêà íå ÿâëÿåòñÿ êðàò-
íîé.
Êðàòíóþ ñòðîêó ìîæíî çàïèñàòü â âèäå S = (U)r. Ó ëþ-
áîé êðàòíîé ñòðîêè S îáðàçóþùàÿ U íå ÿâëÿåòñÿ êðàòíîé.
Ïîñòàíîâêà çàäà÷è. Ïóñòü äàí òåêñò T[1..n]. Òðåáóåòñÿ
íàéòè âñå êðàòíûå ïîäñòðîêè T.
Îïèñûâàòü âõîæäåíèå êðàòíîé ñòðîêè S â T ìîæíî
òðîéêîé ÷èñåë (i, p, r), ãäå i — èíäåêñ ïîçèöèè ñèìâîëà â T,
ñ êîòîðîãî íà÷èíàåòñÿ S; p — êîëè÷åñòâî ñèìâîëîâ â îáðàçó-
þùåé; r — êðàòíîñòü.
Ïðèìåð
S = aababbbaa.
Îòâåò: (1, 1, 2), (2, 2, 2), (5, 1, 3), (8, 1, 2).
Àëãîðèòì Ì. Êðî÷åìîðà ïîäâåðãàåò òåêñò äåêîìïîçè-
öèè. Äëÿ ýòîãî íà êàæäîì øàãå (óðîâíå) L àëãîðèòì íàõîäèò
óíèêàëüíûå ïîäñòðîêè äëèíîé L. Ïðè L = 1 âû÷èñëÿþòñÿ
ïîñëåäîâàòåëüíîñòè ïîçèöèé, â êîòîðûõ âñòðå÷àþòñÿ îäè-
íàêîâûå ñèìâîëû. Äàëåå äëÿ óðîâíåé L > 1 íàõîäÿòñÿ ïî-
ñëåäîâàòåëüíîñòè ïîçèöèé, ñ êîòîðûõ íà÷èíàþòñÿ îäèíàêî-
âûå ïîäñòðîêè äëèíîé L.
Ïðèìåð
Òåêñò T ïðèâåäåí â òàáë. 2.21 (â ïåðâîé ñòðîêå óêàçàíû
íîìåðà ïîçèöèè ñèìâîëîâ â òåêñòå).
Òàáëèöà 2.21
i 1 2 3 4 5 6 7 8 9 10
T a a b a b b b a b $
Íàáëþäåíèå 1.
Âîçüìåì èíäåêñû èç îäíîé ïîñëåäîâàòåëüíîñòè óðîâíÿ
L (íàïðèìåð, i1 è i2) è ïðèáàâèì ê íèì ïî åäèíèöå:
j1 = i1 + 1, j2=i2+1. Åñëè îêàæåòñÿ, ÷òî j1 è j2 ïðèíàäëåæàò
îäíîé ïîñëåäîâàòåëüíîñòè óðîâíÿ L, òî íà óðîâíå L + 1 èí-
äåêñû i1 è i2 ñëåäóåò âêëþ÷èòü â îäíó ïîäïîñëåäîâàòåëü-
íîñòü.
Îáîñíîâàíèå ýòîãî ôàêòà «ëåæèò íà ïîâåðõíîñòè». Äåé-
ñòâèòåëüíî, ïóñòü A — ñòðîêà, ñîîòâåòñòâóþùàÿ îäíîé ïî-
84 Ãëàâà 2. Êëàññè÷åñêèå àëãîðèòìû îáðàáîòêè ñòðîê
Íàáëþäåíèå 2.
Ñíîâà îáðàòèìñÿ ê ïðèìåðó íà ðèñ. 2.13. Ïóñòü íåîáõî-
äèìî ðàçáèòü ïîñëåäîâàòåëüíîñòü {2, 4, 7, 10} íà âòîðîì
óðîâíå. Ýòà ïîñëåäîâàòåëüíîñòü ñîîòâåòñòâóåò ïîäñòðîêå bc,
èìåþùåé ñóôôèêñ c. Ïîñëåäîâàòåëüíîñòü, ñîîòâåòñòâóþ-
ùàÿ ñóôôèêñó c íà ïåðâîì óðîâíå, áûëà ðàçáèòà íà äâå ïîä-
ïîñëåäîâàòåëüíîñòè: {3} è {5, 8, 11}. Îäíà èç íèõ — êîðîò-
2.6. Àëãîðèòì Ì. Êðî÷åìîðà 85
@ Óïðàæíåíèÿ
1. Äàíà ñòðîêà S èç n ñèìâîëîâ (àëôàâèò A óïîðÿäî÷åí,
êàæäûé ñèìâîë èìååò èíäåêñ). Çà âðåìÿ O(n) ïîäñ÷èòàé-
òå êîëè÷åñòâî âõîæäåíèé êàæäîãî ñèìâîëà â ñòðîêó S.
2. Ðàçðàáîòàéòå àëãîðèòì ðàçáèâêè òåêñòà íà óíèêàëüíûå
ïîäñòðîêè ñ âðåìåííîé ñëîæíîñòüþ O(n2).
3. Ïðèâåäèòå ïðèìåð òåêñòà. Âûïîëíèòå åãî äåêîìïîçèöèþ
ñ èñïîëüçîâàíèåì òîëüêî ïîñëåäîâàòåëüíîñòåé èíäåêñîâ
íà êàæäîì óðîâíå (ê ñèìâîëàì òåêñòà ìîæíî îáðàùàòüñÿ
òîëüêî íà ïåðâîì óðîâíå). Ïðîâåðüòå ðåçóëüòàò.
4. Ïðèâåäèòå ïðèìåð òåêñòà. Âûïîëíèòå åãî äåêîìïîçè-
öèþ òàê, êàê ýòî óêàçàíî â ïðåäûäóùåì óïðàæíåíèè, à
òàêæå ñ ó÷åòîì ïðèíöèïà ìàëûõ èíäåêñîâ.
5. Äëÿ âûâîäà êðàòíûõ ñòðîê ñ ïåðèîäîì L íåîáõîäèìî â
êàæäîé ïîñëåäîâàòåëüíîñòè èíäåêñîâ óðîâíÿ L íàéòè
ãðóïïû èäóùèõ ïîäðÿä èíäåêñîâ ñ ïåðèîäîì L. Íàïðè-
ìåð, íà ðèñ. 2.6 ïðè L = 1 ýòî 1, 2 (a2) èç ïåðâîé ïîñëåäî-
âàòåëüíîñòè è 5, 6, 7 (b3) èç âòîðîé, à ïðè L = 2 — 2, 4
(ab2). Ïðåäëîæèòå ñòðóêòóðó äàííûõ äëÿ õðàíåíèÿ èí-
äåêñîâ ïîñëåäîâàòåëüíîñòåé è ðàçðàáîòàéòå ïðîãðàììó
âûâîäà êðàòíûõ ïîäñòðîê.
6. Ïðåäïîëîæèì, ÷òî äëÿ õðàíåíèÿ ïîñëåäîâàòåëüíîñòåé
íà êàæäîì óðîâíå èñïîëüçóåòñÿ ìàññèâ sq âèäà
2.6. Àëãîðèòì Ì. Êðî÷åìîðà 87
Òàáëèöà 2.22
num 1 2 3 4 5 6 7 8 9 10
L=1
mark 1 1 2 1 2 2 2 1 2 3
num 1 2 3 4 5 6 7 8 9 –
L=2
mark 1 2 3 2 4 4 3 2 5 –
Ïðèìåð
S = babaabab. Ðàçîáüåì S íà äâå ðàâíûå ïîäñòðîêè (ïî-
ëîâèíû): u = baba è v = abab, ò. å. S = uv. Òîãäà â S ñóùåñò-
âóþò êâàäðàòû òðåõ òèïîâ:
2
l ïîëíîñòüþ íàõîäÿùèåñÿ â u – (ba) ;
2
l ïîëíîñòüþ íàõîäÿùèåñÿ â v – (ab) ;
2
l íà÷èíàþùèåñÿ â u è çàêàí÷èâàþùèåñÿ â v – (aba) ;
2
(a) .
Èäåÿ àëãîðèòìà.
Âû÷èñëèì âñå êâàäðàòû ñòðîêè S ïóòåì ðåêóðñèâíîé
ðàçáèâêè ñòðîêè S ïîïîëàì è âû÷èñëåíèÿ êâàäðàòîâ òðåòüå-
ãî òèïà. (Î÷åâèäíî, ÷òî â ýòîì ñëó÷àå îïðåäåëÿþòñÿ êâàäðà-
òû è ïåðâûõ äâóõ òèïîâ.) Åñëè ïðè ýòîì øàã ðåêóðñèè áóäåò
âûïîëíÿòüñÿ çà ëèíåéíîå âðåìÿ, òî îáùåå âðåìÿ ðàáîòû òà-
êîãî àëãîðèòìà áóäåò èìåòü îöåíêó O(n · log2n) — àíà-
ëîãè÷íî áèíàðíîìó ïîèñêó.
Çàïèøåì ñêàçàííîå â äðóãîì âèäå.
Procedure Solve(S:String); {n=Length(S)}
Begin
If n>1 Then Begin
<âû÷èñëåíèå êâàäðàòîâ òðåòüåãî òèïà
äëÿ u=S[1..ën/2û] è v=S[ën/2û+1..n]>;
Solve(u);
Solve(v);
End;
End;
öèè k â u: k = n1 + j – w + 1 = n1 + i – w – w + 1 = n1 –
– (2w – i – 1). ×òîáû â ïîçèöèè i çàêàí÷èâàëñÿ êâàäðàò
äëèíîé w, òðåáóåòñÿ âûïîëíåíèå ðàâåíñòâà: u[k..n1]v[1..j] =
= v[j + 1..i], à îíî ðàçáèâàåòñÿ íà äâå ÷àñòè (ðèñ. 2.15á):
l v[1..j] = v[i – j + 1..i] èëè v[1..i – w] = v[w + 1..i];
l u[k..n1] = v[j + 1..i – j] èëè u[n1 – (2w – i – 1)..n1] =
= v[i – w + 1..w].
Ïåðâîå ðàâåíñòâî — ýòî íå ÷òî èíîå, êàê ãðàíü ñòðîêè v â
ïîçèöèè i (ñì. ï. 1.2.1), êîòîðàÿ âû÷èñëÿåòñÿ çà ëèíåéíîå
âðåìÿ. (Íàïîìíèì, ÷òî ãðàíü v[1..i] — ýòî äëèíà íàèáîëü-
øåãî ïðåôèêñà ñòðîêè, ñîâïàäàþùåãî ñ åå ñóôôèêñîì.)
Èòàê, íàì íåîáõîäèìî âû÷èñëèòü ìàññèâ ãðàíåé äëÿ v (îáîç-
íà÷èì åãî êàê brv). Âòîðàÿ æå ÷àñòü ðàâåíñòâà òðåáóåò çíà-
íèÿ îáùèõ ñóôôèêñîâ ñòðîêè u è ïîäñòðîê v (îáîçíà÷èì
ìàññèâ îáùèõ ñóôôèêñîâ êàê csv), ò. å. csv[t] — ýòî äëèíà íà-
èáîëüøåãî ñóôôèêñà ñòðîêè u è ïîäñòðîêè v[1..t]. Ïðåäïî-
ëîæèì, ÷òî çà ëèíåéíîå âðåìÿ âû÷èñëÿåòñÿ íå òîëüêî ìàñ-
ñèâ ãðàíåé brv, íî è csv. Êàê íà îñíîâå ýòîé èíôîðìàöèè
îïðåäåëèòü íàëè÷èå ïðàâûõ êâàäðàòîâ?
Ïðèìåðû
 òàáë. 2.23 è 2.24 äàíû ñòðîêè S = uv, äëÿ êîòîðûõ
ïîäñ÷èòàíû çíà÷åíèÿ ýëåìåíòîâ ìàññèâîâ brv è csv.
Òàáëèöà 2.23
u v
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
a b c a b d a b c a b d a b c a b d a b c a b c
i 1 2 3 4 5 6 7 8 9 0 1 2
brv 0 0 0 1 2 0 1 2 3 4 5 3
csv 0 0 0 0 0 6 0 0 0 0 0 0
Òàáëèöà 2.24
u v
1 2 3 4 5 6 7 8 9 10 11 12 13
a b a a b a b a a b a b a
i 1 2 3 4 5 6 7
brv 0 0 0 1 2 1 2
csv 0 2 1 0 5 0 3
2.7. Àëãîðèòì Ì. Ìåéíà – Ð. Ëîðåíöà 91
Òàáëèöà 2.25
u v
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
a b a b c a b a d a b c a b a d a a b c a b c a
1 2 3 4 5 6 7 8 9 0 1 2 i
0 0 3 2 1 0 0 0 0 0 0 0 bwu
3 0 2 0 0 5 0 1 0 2 0 0 cpu
Òàáëèöà 2.26
u v
1 2 3 4 5 6 7 8 9 10 11 12 13
a b a a b a b a a b a b a
1 2 3 4 5 6 i
1 2 1 1 0 0 bwu
0 5 0 0 2 0 cpu
2.7. Àëãîðèòì Ì. Ìåéíà – Ð. Ëîðåíöà 93
Ïðèìåð
 òàáë. 2.27 ïðåäñòàâëåíû äàííûå åùå ïî îäíîé ñòðîêå,
äëÿ êîòîðîé òðåáóåòñÿ íàéòè âñå åå êâàäðàòû. Ïðîâåðèì
íàëè÷èå ïðàâûõ êâàäðàòîâ, — à õîòÿ áû îäèí òàêîâîé ó íàñ
ÿâíî åñòü — abcdcabcabcdcabc.
Òàáëèöà 2.27
u v
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
a a a b c d c a b c a b c d c a b c
i 1 2 3 4 5 6 7 8 9
brv 0 0 0 1 0 1 2 3 4
csv 0 0 3 0 0 0 0 7 0
@ Óïðàæíåíèÿ
1. Ïðèâåäèòå ïðèìåð ñòðîêè S. Âûïèøèòå âñå åå êâàäðàòû
â òîé î÷åðåäíîñòè, â êîòîðîé îíè áóäóò âûâåäåíû ïðè
ðåêóðñèâíîé ðåàëèçàöèè àëãîðèòìà Ì. Ìåéíà – Ð. Ëî-
ðåíöà.
98 Ãëàâà 2. Êëàññè÷åñêèå àëãîðèòìû îáðàáîòêè ñòðîê
cpu[2]:=0;
While (v[cpu[2]+1]=u[cpu[2]+2]) Do
cpu[2]:=cpu[2]+1;
k:=2;
For i:=3 To Length(u) Do Begin
l:=k+cpu[k]–i;
If blv[i–k+1]<l Then cpu[i]:=blv[i–k+1]
Else cpu[i]:=max(0,l);
While (v[cpu[i]+1]=u[cpu[i]+i]) Do
cpu[i]:=cpu[i]+1;
k:= i;
End;
End;
7. Ñ ïîìîùüþ ïðîöåäóðû Bwu âû÷èñëÿþòñÿ çíà÷åíèÿ ýëå-
ìåíòîâ ìàññèâà bwu — ãðàíè ñóôôèêñîâ ïîäñòðîêè u.
Ïðîâåðüòå åå ðàáîòîñïîñîáíîñòü. Ñðàâíèòå äàííóþ ëîãè-
êó âû÷èñëåíèÿ ñ ïðèâåäåííîé â ï. 1.2.1.
Procedure Bwu(s:String);
Var i, k, l, n1:Byte;
Begin
s:='@'+s;
n1:=Length(s);
While s[n1-bwu[(n1-1)-1]]=
s[(n1-bwu[(n1-1)-1])-1] Do
bwu[(n1-1)-1]:=bwu[(n1-1)-1]+1;
k:=n1-1;
For i:=n1-2 DownTo 1 Do Begin
l:=bwu[k-1]-(k-i);
If bwu[(n1-(k-i)+1)-1]<l Then
bwu[i-1]:=bwu[(n1-(k-i)+1)-1]
Else bwu[i-1]:=max(0,l);
While (s[n1-bwu[i-1]]=s[i-bwu[i-1]]) Do
bwu[i-1]:=bwu[i-1]+1;
k:=i;
End;
End;
8. Îïðåäåëèòå ïî ïðîöåäóðå Csv ëîãèêó ôîðìèðîâàíèÿ
ìàññèâà csv — äëèí íàèáîëüøèõ îáùèõ ñóôôèêñîâ ñòðî-
êè u è ïîäñòðîê v[1..t] (t = 1..n2).
100 Ãëàâà 2. Êëàññè÷åñêèå àëãîðèòìû îáðàáîòêè ñòðîê
Procedure Csv(u,v:String);
Var i, k, l, n1, n2:Byte;
Begin
v:='$'+v;
u:='@'+u;
n1:=Length(u);
n2:=Length(v);
While u[n1-csv[n2-1]]=v[n2-csv[n2-1]] Do
csv[n2-1]:=csv[n2-1]+1;
k:=n2;
For i:=n2-1 DownTo 1 Do Begin
l:=csv[k-1]-(k-i);
If bwu[n1-(k-i)+1]<l Then
csv[i-1]:=bwu[n1-(k-i)+1]
Else csv[i-1]:=max(0,l);
While (u[n1-csv[i-1]]=v[i-csv[i-1]]) Do
csv[i-1]:=csv[i-1]+1;
k:=i;
End;
End;
9. Ïðèâåäåííûé íèæå ôðàãìåíò ïðîãðàììíîãî êîäà îáåñ-
ïå÷èâàåò âûâîä êâàäðàòîâ. Çíà÷åíèå ïåðåìåííîé c ðàâ-
íî 1 ëèáî n1 + 1 (â çàâèñèìîñòè îò òîãî, âûçûâàåòñÿ ëî-
ãèêà ñ u èëè ñ v). Óëó÷øèòå ýòîò ïðîãðàììíûé êîä.
w:=1;
While w<=n2 Do Begin
If (blv[w+1]+csv[w]>=w) Then Begin
WriteLn('(',w,',',((2*w-csv[w])+n1+c-1)-
2*w+1,',',((w+blv[w+1])+n1+c-1)-
2*w+1,') R');
For i:=((2*w-csv[w])+n1+c-1)-2*w+1 To
((w+blv[w+1])+n1+c-1)-2*w+1 Do
WriteLn('Ïðàâûé êâàäðàò ',Copy(S,i,2*w),
' ñ äëèíîé=',w,' è íà÷àëîì
â ïîçèöèè ',i);
End;
If (cpu[(n1-w)+1]+bwu[n1-w]>=w) And (w<n1)
Then Begin
If (((n1-w)-bwu[n1-w])+1)=
((n1-2*w)+cpu[(n1-w)+1]+1)
2.7. Àëãîðèòì Ì. Ìåéíà – Ð. Ëîðåíöà 101
Then WriteLn('(',w,',',(((n1-w)-bwu[n1-w])
+1)+c-1,',',((n1-2*w)+
cpu[(n1-w)+1]+1)+c-1,') L')
Else WriteLn('(',w,',',(((n1-w)-bwu[n1-w])
+1)+c-1,',',((n1-2*w)+bwu[(n1
-p)+1]+1)+c-2,') L');
For i:=(((n1-w)-bwu[n1-w])+1)+c-1 To
((n1-2*w)+cpu[(n1-w)+1]+1)+c-2 Do
WriteLn('Ëåâûé êâàäðàò ',Copy(S,i,2*w),
' ñ äëèíîé=',w,' è íà÷àëîì
â ïîçèöèè ',i);
End;
w:=w+1;
End;
10. Ðàçðàáîòàéòå ïîëíóþ ïðîãðàììíóþ ðåàëèçàöèþ àëãî-
ðèòìà Ì. Ìåéíà – Ð. Ëîðåíöà.
Ìåòîäè÷åñêèé êîììåíòàðèé
Àëãîðèòìû Ä. Êíóòà (Donald Knuth) – Äæ. Ìîððèñà
(James Morris) – Â. Ïðàòòà (Vaughan Pratt)1) è Ð. Áîéåðà
(Robert Boyer) – Äæ. Ìóðà (James Moore)2) ÿâëÿþòñÿ êëàññè-
êîé äàííîãî ðàçäåëà èíôîðìàòèêè (computer science). Â òîé
èëè èíîé ìåðå îíè çàòðàãèâàþòñÿ âî ìíîãèõ ó÷åáíèêàõ ïî èí-
ôîðìàòèêå ïðè èçó÷åíèè òåìû ïîèñêà äàííûõ, âêëþ÷àÿ êëàñ-
ñè÷åñêóþ ðàáîòó Í. Âèðòà (Niklaus Wirth)3).
Ð. Êàðï (Richard Karp) è Ì. Ðàáèí (Michael Rabin)4) îïóá-
ëèêîâàëè ñâîé ìåòîä ïîèñêà îáðàçöà â òåêñòå â 1987 ã. Â ðàáî-
òå Ä. Ãàñôèëäà (ñ. 108), îäíàêî, óòâåðæäàåòñÿ, ÷òî îí èçîáðå-
òåí äåñÿòèëåòèåì ðàíåå. Åñëè àëãîðèòìû Ä. Êíóòà – Äæ. Ìîð-
ðèñà – Â. Ïðàòòà è Ð. Áîéåðà – Äæ. Ìóðà, à òàêæå èõ
ìíîãî÷èñëåííûå ìîäèôèêàöèè, ñäåëàííûå ïîñëå 1977 ã.,
îñíîâàíû íà ñðàâíåíèè ñèìâîëîâ è ñäâèãàõ, òî â äàííîì ìåòî-
äå çàëîæåí ñîâåðøåííî äðóãîé ïðèíöèï — «àðèôìåòè÷åñ-
êèé». Îáðàçåö è ñòðîêà òåêñòà ïðåîáðàçóþòñÿ â ÷èñëà, è ïðî-
èñõîäèò ñðàâíåíèå íå ñèìâîëîâ, à ÷èñåë. Ïðè ýòîì âñå îïðåäå-
ëÿåòñÿ ýôôåêòèâíîñòüþ ïðåîáðàçîâàíèÿ ïîäñòðîêè â ÷èñëî.
1)
Knuth D. E., Morris J. H., Pratt V. R. Fast pattern matching in strings // SIAM J.
Comput. 6–2, 1977. P. 323–350.
2)
Boyer R. S., Moore J. S. A fast string searching algorithm // CACM, 20–10,
1977. P. 762–772.
3)
Âèðò Í. Àëãîðèòìû è ñòðóêòóðû äàííûõ. — Ì.: Ìèð, 1989.
4)
Karp R. M., Rabin M. O. Efficient randomized pattern – matching algorithms //
IBM J. Res. Develop. 31–2, 1987. P. 85–103.
102 Ãëàâà 2. Êëàññè÷åñêèå àëãîðèòìû îáðàáîòêè ñòðîê
1)
Baeza-Yates R. A., Gonzaio N. H. A new approach to text searching // CACM,
35–70, 1992. P. 74–82.
2)
Domolki B. A universal computer system based on production rules // BITS,
1968. P. 262–275.
3)
Crochemore M. An optimal algorithm for computing all the repetitions in a word
// IPL, 12–5, 1981. P. 244–248.
4)
Main M. G., Lorentz R. J. An O(n·logn) algorithm for finding all repetitions in a
string // J. Algs., 5, 1984. P. 422–432.
Ãëàâà 3
Äåðåâüÿ ñóôôèêñîâ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
a b c a b d a b c a b d a b $
num:Integer;
{Ìåòêà ëèñòà. Äëÿ âíóòðåííåé âåðøèíû, âêëþ÷àÿ
êîðåíü, îíà èìååò çíà÷åíèå 0}
End;
End;
Var
S:String;
n:Integer;
tree:PList;
 êàæäîé âåðøèíå äåðåâà ìû âûíóæäåíû ââîäèòü ìàñ-
ñèâ d, ïîñêîëüêó ìàêñèìàëüíîå êîëè÷åñòâî äóã, âûõîäÿùèõ
èç âåðøèíû, ðàâíî ìîùíîñòè àëôàâèòà A. Îïèñàíèå ñòðîêè
S, òàêîå, ÷òî îãðàíè÷åíèå íà åå ðàçìåð îïðåäåëÿåòñÿ ñèñòå-
ìîé ïðîãðàììèðîâàíèÿ, âçÿòî çäåñü äëÿ ïðîñòîòû.
Ïðèâåäåì îäèí èç âîçìîæíûõ ñïîñîáîâ ðåàëèçàöèè ðàñ-
ñìîòðåííîãî àëãîðèòìà.
Procedure TreeSuf1;
Var w,v: PList;
i,j,l,t:Integer;
bl:Boolean;
Begin
S:=S+'$';
n:=Length(S);
{Ïåðâûé øàã àëãîðèòìà – â êîðíå äåðåâà äàåòñÿ
îïèñàíèå äóãè, èäóùåé â âåðøèíó ñ ìåòêîé "1"}
st:=1; {Íîìåð ëèñòà}
New(tree);
tree^.cnt:=1;
tree^.d[1].first:=1;
tree^.d[1].last:=n;
tree^.d[1].next:=Nil;
tree^.d[1].num:=st;
{Ñóôôèêñ S[i..n] îïèñûâàåì (ïðåäñòàâëÿåì) â äåðåâå}
For i:=2 To n Do Begin
w:=tree;
t:=i;
bl:=False;
While Not bl Do Begin
{Ïîêà íå ñôîðìèðîâàí ëèñò, ñîîòâåòñòâóþùèé
ñóôôèêñó, âûïîëíÿåì äåéñòâèÿ öèêëà}
108 Ãëàâà 3. Äåðåâüÿ ñóôôèêñîâ
j:=1;
l:=0;
While (l=0)And(j<=w^.cnt) Do Begin
{Ïðîñìàòðèâàåì äóãè, âûõîäÿùèå èç âåðøèíû,
íà êîòîðóþ "ñìîòðèò" w^}
If S[w^.d[j].first]=S[t] Then l:=j;
{Äóãà íàéäåíà – ïåðâûé ñèìâîë ñóôôèêñà ñîâïàäàåò
ñ ïåðâûì ñèìâîëîì ìåòêè äóãè}
j:=j+1;
End;
If l=0 Then Begin
{Äóãà íå íàéäåíà – ñîçäàåì íîâóþ âåðøèíó-ëèñò,
îòöîì êîòîðîé ÿâëÿåòñÿ âåðøèíà w^}
w^.cnt:=w^.cnt+1;
st:=st+1;
bl:=True; {Ñóôôèêñ îáðàáîòàí}
w^.d[w^.cnt].next:=Nil;
w^.d[w^.cnt].num:=st;
w^.d[w^.cnt].first:=t;
w^.d[w^.cnt].last:=n;
End
Else Begin
{Äóãà íàéäåíà – ñðàâíèâàåì ñèìâîëû ñóôôèêñà
è ìåòêè äóãè}
j:=1;
While (w^.d[l].first+j<=w^.d[l].last) And
(S[t+j]=S[w^.d[l].first+j]) Do
j:=j+1;
If w^.d[l].first+j<=w^.d[l].last Then
Begin
{Ñîçäàåì íîâóþ âíóòðåííþþ âåðøèíó}
st:=st+1;
New(v);
v^.cnt:=2; {Ó âåðøèíû äâà ñûíà}
v^.d[1].next:=w^.d[l].next;
{Íîâàÿ ìåòêà äóãè – ñîâïàäàþùàÿ ÷àñòü ñóôôèêñà
è ñòàðîé ìåòêè äóãè}
v^.d[1].num:=w^.d[l].num;
v^.d[1].first:=w^.d[l].first+j;
v^.d[1].last:=w^.d[l].last;
v^.d[2].next:=Nil;
3.1. Îñíîâíûå ïîíÿòèÿ è ïîñòðîåíèå äåðåâà ñóôôèêñîâ 109
Òàáëèöà 3.2
Íîìåð
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
ñèìâîëà
Øàã a b c a b d a b c a b d a b $
1 2
2 1 2
3 1 1 2
4 1 1 1 3
5 1 1 1 3 3
6 1 1 1 2 2 2
7 1 1 1 1 1 1 3
8 1 1 1 1 1 1 3 3
9 1 1 1 1 1 1 3 3 3
10 1 1 1 1 1 1 3 3 3 3
11 1 1 1 1 1 1 3 3 3 3 3
12 1 1 1 1 1 1 3 3 3 3 3 3
13 1 1 1 1 1 1 3 3 3 3 3 3 3
14 1 1 1 1 1 1 3 3 3 3 3 3 3 3
15 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2
Procedure TreeSuf2;
Var w,v: PList;
i,j,l,t,k:Integer;
bl,bl1:Boolean;
Begin
S:=S+'$';
n:=Length(S);
st:=1;
New(tree); {Ñîçäàåì ïåðâóþ âåðøèíó}
tree^.cnt:=1;
tree^.d[1].first:=1;
tree^.d[1].last:=1;
tree^.d[1].next:=Nil;
tree^.d[1].num:=st;
For i:=2 To n Do Begin
{Îáðàáàòûâàåì ñòðîêè S[1..i] – èçìåíÿåì äåðåâî
ñóôôèêñîâ}
k:=1;
3.1. Îñíîâíûå ïîíÿòèÿ è ïîñòðîåíèå äåðåâà ñóôôèêñîâ 115
End;
End;
End;
@ Óïðàæíåíèÿ
1. Ïîñòðîéòå ïåðâûì ñïîñîáîì äåðåâüÿ ñóôôèêñîâ äëÿ
ñòðîê:
l abcdefghijklmnopq;
l aaaaaaaaaaaaaaaab;
l abaababa;
l abaababaabaab;
l abaababaabaababaababa;
l abbabaab;
l abbabaabbaababba;
l abcabacabcbacbcacb;
l abcabacabcbacbcacbabcabacabcb.
Ïðèìåð
Äàíà ñòðîêà, ïðåäñòàâëåííàÿ â òàáë. 3.3.
Òàáëèöà 3.3
Íîìåð
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
ïîçèöèè
S b a c b a b a b a a b c b a b $
@ Óïðàæíåíèÿ
1. Èñïîëüçóÿ àëãîðèòì Ý. Óêêîíåíà, ïîñòðîéòå äåðåâüÿ
ñóôôèêñîâ ñ ñóôôèêñíûìè ñâÿçÿìè äëÿ ñòðîê:
l abcdefghijklmnopq;
l aaaaaaaaaaaaaaaab;
l abaababa;
l abaababaabaab;
l abaababaabaababaababa;
l abbabaab;
l abbabaabbaababba;
l abcabacabcbacbcacb;
l abcabacabcbacbcacbabcabacabcb.
Òàáëèöà 3.4
Ïðèìåð
Ïîñòðîèì äåðåâî ñóôôèêñîâ äëÿ ñòðîêè abaaaabaaaab$.
(Øàãè 3–8 ïîêàçàíû íà ðèñ. 3.13, à øàãè 9–12 — íà
ðèñ. 3.14.)
130 Ãëàâà 3. Äåðåâüÿ ñóôôèêñîâ
@ Óïðàæíåíèÿ
1. Èçìåíèòå ñòðîêó abaaaabaaaab$ íà abaaaabaaaabaaaab$
è ïðîäîëæèòå ïîñòðîåíèå äåðåâà ñóôôèêñîâ, ïîêàçàííî-
ãî íà ðèñ. 3.13 è ðèñ. 3.14.
2. Íàïèøèòå ïðîãðàììó âû÷èñëåíèÿ çíà÷åíèé head[i] äëÿ
ïðîèçâîëüíîé ñòðîêè S.
3. Ïðåäïîëîæèì, ÷òî çàäàíî ñëåäóþùåå îïèñàíèå âåðøè-
íû äåðåâà ñóôôèêñîâ:
tree=^node;
node=Record
cnt:Word;
{Êîëè÷åñòâî ñûíîâåé}
134 Ãëàâà 3. Äåðåâüÿ ñóôôèêñîâ
parent:tree;
{Ññûëêà íà ðîäèòåëÿ}
first,last:Word;
{Èíäåêñû íà÷àëà è êîíöà ìåòêè äóãè}
suf:tree;
{Ñóôôèêñíàÿ ñâÿçü}
num:Word;
{Ìåòêà âåðøèíû}
ln:Word;
{Êîëè÷åñòâî ñèìâîëîâ â ñòðîêå, ïîëó÷àåìîé
"ñêëåéêîé" ìåòîê äóã íà ïóòè îò êîðíÿ
äî âåðøèíû}
next:Array[1..|A|] Of tree;
{Ìàññèâ óêàçàòåëåé íà ñûíîâåé âåðøèíû}
End;
Çäåñü â ïåðåìåííîé pt õðàíèòñÿ óêàçàòåëü íà êîðåíü äå-
ðåâà (íà ìîìåíò âûçîâà ïðîöåäóðû). Íàéäèòå âîçìîæ-
íîñòü óëó÷øèòü ïðîãðàììíûé êîä ïðîöåäóðû Search —
ïîèñêà îáðàçöà P â òåêñòå T ïðè ïîñòðîåííîì äåðåâå
ñóôôèêñîâ.
Procedure Search;
Var i,j,r:Word;
fn:Boolean; {Ïðèçíàê çàâåðøåíèÿ ðàáîòû}
Begin
r:=1; {Íîìåð ñèìâîëà â P}
fn:=False;
Repeat
i:=1;
While (i<=pt^.cnt) And
(T[pt^.next[i]^.first]<>P[r]) Do i:=i+1;
If (i>pt^.cnt) Then Begin
WriteLn('P íåò â òåêñòå');
fn:=True;
End
Else Begin
pt:=pt^.next[i];
j:=1;
While (T[pt^.first+j]=P[r+j]) And
(pt^.first+j<=pt^.last) And
(r+j<=m) Do j:=j+1;
3.3. Àëãîðèòì Å. Ìàê-Êðåéãà 135
Òàáëèöà 3.5
Íîìåð
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
ïîçèöèè
T a b a a b a b a a b a a b
T b a c b a b a b a a b c b a b a
Òàáëèöà 3.6
Íîìåð
Íîìåð Íîìåð
ýëåìåíòà
ñóô- Ñóôôèêñ ñóô- Ñóôôèêñ
ìàññèâà
ôèêñà ôèêñà
ArSuf
1 11 aab 16 a
2 8 aabaab 9 aabcbaba
3 3 aababaabaab 14 aba
4 12 ab 7 abaabcbaba
5 9 abaab 5 ababaabcbaba
6 6 abaabaab 10 abcbaba
7 1 abaababaabaab 2 acbababaabcbaba
8 4 ababaabaab 15 ba
9 13 b 8 baabcbaba
10 10 baab 13 baba
11 7 baabaab 6 babaabcbaba
12 2 baababaabaab 4 bababaabcbaba
13 5 babaabaab 1 bacbababaabcbaba
14 11 bcbaba
15 12 cbaba
16 3 cbababaabcbaba
138 Ãëàâà 3. Äåðåâüÿ ñóôôèêñîâ
Ïðèìåð
Ïóñòü äàí òåêñò T = abaaaabaaaabaaba. Ìàññèâ ñóô-
ôèêñîâ ArSuf äëÿ T ïðåäñòàâëåí â òàáë. 3.7.
Òàáëèöà 3.7
Íîìåð ýëåìåíòà
Íîìåð ñóôôèêñà Ñóôôèêñ
ìàññèâà ArSuf
1 16 a
2 3 aaaabaaaabaaba
3 8 aaaabaaba
4 9 aaabaaba
5 4 aaabaaaabaaba
6 13 aaba
7 5 aabaaaabaaba
8 10 aabaaba
9 14 aba
10 1 abaaaabaaaabaaba
11 6 abaaaabaaba
12 11 abaaba
13 15 ba
14 2 baaaabaaaabaaba
15 7 baaaabaaba
16 12 baaba
Òàáëèöà 3.8
l r ll lr q lt lq lt Ñðàâíåíèå
P = aaaba 1 16 1 0 8 0 2 2 P[3] < T[15]
1 8 1 2 4 1 3 4 Ýëåìåíò íàéäåí
P = aabaa 1 16 1 0 8 0 4 4 P[5] < T[17]
1 8 1 4 4 1 1 2 P[3] > T[11]
4 8 2 4 6 2 3 5 Ýëåìåíò íàéäåí
142 Ãëàâà 3. Äåðåâüÿ ñóôôèêñîâ
@ Óïðàæíåíèÿ
1. Íàïèøèòå ïðîöåäóðó ôîðìèðîâàíèÿ ñóôôèêñíîãî ìàñ-
ñèâà èç äåðåâà ñóôôèêñîâ.
2. Ñ ïîìîùüþ ôóíêöèè PSearch îáåñïå÷èâàåòñÿ íàõîæäå-
íèå åäèíñòâåííîãî âõîæäåíèÿ P â T. Ðàçðàáîòàéòå ëî-
ãèêó ïîèñêà âñåõ âõîæäåíèé P â T.
3. Ïðèâåäèòå ïðèìåð (çíà÷åíèÿ T è P), â êîòîðîì ôóíêöèÿ
PMSearch íå óìåíüøàåò êîëè÷åñòâà ñðàâíåíèé ñèì-
âîëîâ ïî îòíîøåíèþ ê ôóíêöèè PSearch.
4. Ïðèâåäèòå ïðèìåð äëÿ ñëó÷àÿ, êîãäà êîëè÷åñòâî íåñîâ-
ïàäåíèé â àëãîðèòìå (âòîðîì) â òî÷íîñòè ðàâíî log2n.
5. Íàéäèòå ñïîñîá õðàíåíèÿ çíà÷åíèé lcp â îäíîìåðíîì
ìàññèâå.
6. Ïðèâåäèòå ïðèìåð ñòðîêè. Âû÷èñëèòå äëÿ íåå ìàññèâû
ArSuf è lcp.
7. Ðàçðàáîòàéòå ïðîãðàììíóþ ðåàëèçàöèþ òðåòüåãî àëãî-
ðèòìà ïîèñêà P â T.
Ïðèìåð
Ïóñòü äàíî ìíîæåñòâî îáðàçöîâ: P1 = abcdccb,
P2 = bcdccb, P3 = dccb, P4 = bc, P5 = dc, P6 = cb. Äåðåâî
êëþ÷åé äëÿ Pi (i = 1, …, 6) ïîêàçàíî íà ðèñ. 3.20.
Òàáëèöà 3.9
F 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
a 1 0 8 9 10 11 12 13 0 18 14 15 16 17 0 18 18 19 0 8
b 8 2 8 9 10 11 7 13 0 18 14 15 13 17 0 18 17 19 19 8
c 18 0 3 9 5 6 12 13 9 18 11 12 16 17 15 16 18 19 0 8
d 14 0 8 4 10 11 12 13 0 10 14 15 16 17 0 18 18 19 0 8
Òàáëèöà 3.10
Òàáëèöà 3.11
@ Óïðàæíåíèÿ
1. Ðàçðàáîòàéòå ïðîñòîé àëãîðèòì ïîèñêà îáðàçöîâ â òåê-
ñòå ñ âðåìåííîé îöåíêîé O(t · n · m), ãäå m — ñóììàðíàÿ
äëèíà îáðàçöîâ.
2. Ïðèâåäèòå ïðèìåð ìíîæåñòâà îáðàçöîâ, äëÿ êîòîðîãî
äèàãðàììà ïåðåõîäîâ àâòîìàòà íå áóäåò èìåòü ïóíêòèð-
íûõ ñâÿçåé (ñì. ðèñ. 3.21). Êàê â ýòîì ñëó÷àå ðàáîòàåò
àëãîðèòì À. Àõî – Ì. Êîðàñèê?
3. Ïðèâåäèòå ïðèìåð ìíîæåñòâà îáðàçöîâ. Ïîñòðîéòå äëÿ
íåãî äåðåâî êëþ÷åé è ïðåîáðàçóéòå åãî â äèàãðàììó ðà-
áîòû àâòîìàòà. Ñôîðìèðóéòå äëÿ êàæäîãî ñîñòîÿíèÿ
ñïèñîê îáðàçöîâ, êîòîðûå ñëåäóåò âûâåñòè ïðè åãî äîñ-
òèæåíèè.
4. Âûÿñíèòå, êàê àëãîðèòì À. Àõî – Ì. Êîðàñèê ðàáîòàåò ñ
ïåðèîäè÷åñêèìè ñòðîêàìè. Ïðèìåð ïåðèîäè÷åñêîé
ñòðîêè: (abc)t, ãäå t — íàòóðàëüíîå ÷èñëî.
5. Ðåàëèçóéòå àëãîðèòì À. Àõî – Ì. Êîðàñèêà (íàïèøèòå
ïðîãðàììó). Îñíîâíàÿ ÷àñòü ëîãèêè ìîæåò âûãëÿäåòü
ñëåäóþùèì îáðàçîì:
Begin
Init; {Èíèöèàëèçàöèÿ äàííûõ}
KeyTree; {Ïîñòðîåíèå äåðåâà êëþ÷åé}
Automat; {Ïîñòðîåíèå àâòîìàòà}
Search; {Ïîèñê âõîæäåíèÿ îáðàçöîâ â òåêñò
ñ âûâîäîì ðåçóëüòàòà}
End;
Ïðèìå÷àíèå. Èçÿùåñòâî ðåàëèçàöèè áóäåò, êàê îáû÷-
íî, çàâèñåòü îò âûáîðà ñòðóêòóð äàííûõ.
Ìåòîäè÷åñêèé êîììåíòàðèé
Ïåðâûé àëãîðèòì ïîñòðîåíèÿ äåðåâà ñóôôèêñîâ (äåðåâà ïî-
çèöèé) çà ëèíåéíîå âðåìÿ ðàçðàáîòàí Ï. Âàéíåðîì1)
(Peter Weiner) â 1973 ã. Çàòåì â 1976 ã. Å. Ìàê-Êðåéãîì2)
(Edward McCreight) áûë ïðåäëîæåí äðóãîé àëãîðèòì. Âàðèàíò
Å. Ìàê-Êðåéãà áîëåå ýêîíîìè÷åí ïî ïàìÿòè.  1995 ã. Ý. Óêêî-
1)
Weiner P. Linear pattern matching algoritms // Proc. of the 14th IEEE Symp. on
Switching and Automata Theory. 1973. P. 1–11.
2)
McCreight E. M. A space-economical suffix tree constructor algorithm //
J. ACM. 1976. Vol. 23. P. 262–272.
154 Ãëàâà 3. Äåðåâüÿ ñóôôèêñîâ
1)
Ukkonen E. On-line construction of suffix–trees // Algorithmica. 1995. Vol. 14.
P. 249–260.
2)
Farach M. Optimal suffix tree construction with large alphabets // Proc. 38th
Annual IEEE Symp. Foundations of Computer Science, 1997. P. 137–143.
3)
Manber U., Myers G. Suffix arrays: a new method for on-line string searches //
Proc. First Annual ACM – SIAM Symp. Discrete Algs., 1990. P. 319–327.
Manber U., Myers G. Suffix arrays: a new method for on-line string searches //
SIAM J. Comput. 22–5, 1993. P. 935–948
4)
Sadakane K. A fast algorithm for making suffix arrays and for Burrows-
Wheeler transformation // Proc. IEEE Data Compression Conference, 1998.
P. 129–138.
5)
Aho A., Corasick M. Efficient string matching: an aid to bibliographic search //
Comm. ACM. 1975. Vol. 18. P. 333–340.
Ãëàâà 4
Âû÷èñëåíèå ðàññòîÿíèÿ
ìåæäó ñòðîêàìè
1)
Ñ÷èòàåì, ÷òî ñ ìåòîäîì äèíàìè÷åñêîãî ïðîãðàììèðîâàíèÿ ÷èòàòåëü çíàêîì,
íàïðèìåð, ïî êíèãå: Îêóëîâ Ñ. Ì. Ïðîãðàììèðîâàíèå â àëãîðèòìàõ. — Ì.:
ÁÈÍÎÌ. Ëàáîðàòîðèÿ çíàíèé, 2007.
156 Ãëàâà 4. Âû÷èñëåíèå ðàññòîÿíèÿ ìåæäó ñòðîêàìè
Ïðèìåð
Ïóñòü S1 = abcd, S2 = acbd. Òîãäà ðàññòîÿíèå Ð. Õåì-
ìèíãà äëÿ ýòèõ ñòðîê d(u1, u2) = 2.
Расстояние В. Левенштейна1) для строк u1 и u2 опðåäå-
ëÿåòñÿ êàê ìèíèìàëüíîå êîëè÷åñòâî îïåðàöèé âñòàâîê (In),
óäàëåíèé (Dl) è ïîäñòàíîâîê (Re), íåîáõîäèìûõ äëÿ ïðåîá-
ðàçîâàíèÿ u1 â u2.
Ïðèìåð
Ïóñòü S1 = abbca, à S2 = aca. Ïîñëåäîâàòåëüíîñòü îïå-
ðàöèé MaReReDlDl íàä ñèìâîëàìè ïåðâîé ñòðîêè (ïåðâûé
ñèìâîë íå èçìåíÿåòñÿ, âòîðîé è òðåòèé çàìåíÿþòñÿ, ÷åòâåð-
òûé è ïÿòûé — óäàëÿþòñÿ) äàåò d(S1,S2) = 4. Àíàëîãè÷íî
ïîñëåäîâàòåëüíîñòü îïåðàöèé MaReDlDlMa ïðèâîäèò ê ðàñ-
ñòîÿíèþ d(S1,S2) = 3, à ïîñëåäîâàòåëüíîñòü MaDlDlMaMa –
d(S1,S2) = 2.
Òàêèì îáðàçîì, åñëè ðå÷ü èäåò î ìèíèìàëüíîì ðàññòîÿ-
íèè, òî ñëåäóåò ïîíèìàòü, ÷òî îïðåäåëÿåòñÿ íå òîëüêî êîí-
êðåòíîå ÷èñëîâîå çíà÷åíèå, íî è ïîñëåäîâàòåëüíîñòü îïåðà-
öèé, ïðèìåíåíèå êîòîðûõ îáåñïå÷èâàåò åãî äîñòèæåíèå.
Êðîìå òîãî, ïåðâàÿ ñòðîêà ïðåîáðàçóåòñÿ âî âòîðóþ, îäíàêî
î÷åâèäíî, ÷òî âñòàâêà ñèìâîëà â îäíó ñòðîêó ìîæåò ðàñ-
1)
Ëåâåíøòåéí Â. È. Äâîè÷íûå êîäû ñ èñïðàâëåíèåì âûïàäåíèé, âñòàâîê è çà-
ìåùåíèé ñèìâîëîâ // Äîêëàäû ÀÍ ÑÑÑÐ. 1965. Ò.163. Ñ. 707–710.
4.1. Îñíîâíîé àëãîðèòì 157
1)
Ðàññòîÿíèå Â. Ëåâåíøòåéíà â ðàçëè÷íûõ èñòî÷íèêàõ îïðåäåëÿþò ïî-ðàçíî-
ìó. Â ðàáîòå Á. Ñìèòà â îïðåäåëåíèè ôèãóðèðóþò òîëüêî îïåðàöèè âñòàâêè è
óäàëåíèÿ, à äëÿ ðàññòîÿíèÿ, îïðåäåëåííîãî òàê, êàê ýòî ñäåëàíî â òåêñòå äàí-
íîé êíèãè, ââîäèòñÿ íîâîå ïîíÿòèå — ðàññòîÿíèå ïðåîáðàçîâàíèÿ.
158 Ãëàâà 4. Âû÷èñëåíèå ðàññòîÿíèÿ ìåæäó ñòðîêàìè
Procedure CreateDist;
Var i,j,t:Word;
Begin
D[0,0]:=0;
For i:=1 To n Do D[i,0]:=i;
For j:=1 To m Do D[0,j]:=j;
For i:=1 To n Do
For j:=1 To m Do Begin
If S1[i]=S2[j] Then t:=0 Else t:=1;
D[i,j]:=Min(D[i-1,j]+1,D[i,j-1]+1,
D[i-1,j-1]+t);
{Ôóíêöèÿ âû÷èñëåíèÿ ìèíèìàëüíîãî èç òðåõ ÷èñåë}
End;
End;
Ïðèìåð 1
S1 = abcdbad, S2 = bacaba. Ìàññèâ D (òàáë. 4.1) çàïîë-
íÿåòñÿ ïîñëåäîâàòåëüíî: ñíà÷àëà ýëåìåíòû ïåðâîé ñòðîêè,
çàòåì — âòîðîé è ò. ä. Çíà÷åíèå D[6, 7] ãîâîðèò î òîì, ÷òî
ñòðîêà S1 ïðåîáðàçóåòñÿ â ñòðîêó S2 çà ÷åòûðå îïåðàöèè.
Òàê, ïîäñòðîêà S1[1..6] = abcdba ïðåîáðàçóåòñÿ â
S2[1..6] = bacaba çà òðè îïåðàöèè (D[6, 6] = 3), à óäàëÿÿ èç
S1[1..7] ïîñëåäíèé ñèìâîë (îäíà îïåðàöèÿ), ìû ïîëó÷àåì
÷åòûðå îïåðàöèè. Ïîäñòðîêà S1[1..6] = abcdba ïðåîáðàçó-
åòñÿ â S2[1..5] = bacab çà ÷åòûðå îïåðàöèè. Âûïîëíÿÿ çàìå-
íó ñèìâîëà S1[7] = d íà ñèìâîë S2[6] = a, ìû èìååì îäíó
îïåðàöèþ, à â èòîãå — ïÿòü. Ïîäñòðîêà S1[1..7] = abcdbad
ïðåîáðàçóåòñÿ â S2[1..5] = bacab çà ïÿòü îïåðàöèé. Âûïîë-
íÿÿ âñòàâêó â S1 ñèìâîëà a, ìû ïîëó÷àåì øåñòü îïåðàöèé.
Ìèíèìàëüíîå èç òðåõ ÷èñåë {3, 4, 5} åñòü 3. Ïî òàêîé æå ëî-
ãèêå â ñîîòâåòñòâèè ñ óñòàíîâëåííîé î÷åðåäíîñòüþ ôîðìè-
ðóþòñÿ è äðóãèå ýëåìåíòû D.
4.1. Îñíîâíîé àëãîðèòì 159
Òàáëèöà 4.1
Íîìåð
D 0 1 2 3 4 5 6 7
ñèìâîëà
Íîìåð
Ñèìâîë a b c d b a d
ñèìâîëà
0 Ñèìâîë 0 1 2 3 4 5 6 7
1 b 1 1 1 2 3 4 5 6
2 a 2 1 2 2 3 4 4 5
3 c 3 2 2 2 3 4 5 6
4 a 4 3 3 3 3 4 4 5
5 b 5 4 3 4 4 3 4 5
6 a 6 5 4 4 5 4 3 4
Ïðèìåð 2
Ñòðîêà S1 = aababab ïðåîáðàçóåòñÿ â S2 = abbaa çà òðè
îïåðàöèè (ìàññèâ D ïðèâåäåí â òàáë. 4.2). Ïîñëåäíåé îïåðà-
öèåé ïî ïðåîáðàçîâàíèþ S1 â S2 ìîæåò áûòü êàê çàìåíà ñèì-
âîëà b íà ñèìâîë a — ìû ïåðåõîäèì èç D[4, 6] â D[5, 7], òàê
è óäàëåíèå ñèìâîëà b èç S1 — ïåðåõîäèì èç D[5, 6] â D[5, 7].
Íî è â òîì, è â äðóãîì ñëó÷àå ïðåîáðàçîâàíèå (S1[1..6] â
S2[1..5] è S1[1..6] â S2[1..4]) îñóùåñòâëÿåòñÿ çà äâå îïåðà-
öèè.
Òàáëèöà 4.2
Íîìåð
D 0 1 2 3 4 5 6 7
ñèìâîëà
Íîìåð
Ñèìâîë a a b a b a b
ñèìâîëà
0 Ñèìâîë 0 1 2 3 4 5 6 7
1 a 1 0 1 2 3 4 5 6
2 b 2 1 1 1 2 3 4 5
3 b 3 2 2 1 2 2 3 4
4 a 4 3 2 2 1 2 2 3
5 a 5 4 3 3 2 2 2 3
160 Ãëàâà 4. Âû÷èñëåíèå ðàññòîÿíèÿ ìåæäó ñòðîêàìè
@ Óïðàæíåíèÿ
1. Ïðèâåäèòå ïðèìåðû ñòðîê S1 è S2. Íàéäèòå âñå ñïîñîáû
ïðåîáðàçîâàíèÿ S1 â S2. Âûáåðèòå èç íèõ òå, êîòîðûå ðå-
øàþò çàäà÷ó çà ìèíèìàëüíîå êîëè÷åñòâî îïåðàöèé.
2. Ïðèâåäèòå ïðèìåðû ñòðîê S1 è S2. Ñôîðìèðóéòå âðó÷-
íóþ ìàññèâ ðàññòîÿíèé D. Âûïîëíèòå îáðàòíûé ïðî-
ñìîòð ìàññèâà D.
3. Ðàçðàáîòàéòå àëãîðèòì âû÷èñëåíèÿ ðàññòîÿíèÿ Õåì-
ìèíãà ìåæäó äâóìÿ ñòðîêàìè äëèíû n.
4. Ïðè èçâåñòíîì ìàññèâå D íàéäèòå ïîñëåäîâàòåëüíîñòü
îïåðàöèé ïî ïðåîáðàçîâàíèþ S1 â S2.
5. Ïðè èçâåñòíûõ ìàññèâàõ D è Dp íàéäèòå âñå ïîñëåäîâà-
òåëüíîñòè îïåðàöèé ïî ïðåîáðàçîâàíèþ S1 â S2.
6. Âçâåøåííîå ðàññòîÿíèå. Îáîçíà÷èì ÷åðåç ds «ñòîè-
ìîñòü» îïåðàöèé âñòàâêè è óäàëåíèÿ ñèìâîëà, ÷åðåç
rs — «ñòîèìîñòü» îïåðàöèè ïîäñòàíîâêè èëè çàìåíû, à
÷åðåç es — «ñòîèìîñòü» ñîâïàäåíèÿ. Ñòàâèòñÿ çàäà÷à ïå-
ðåâîäà ñòðîêè S1 â ñòðîêó S2 ñ ìèíèìàëüíîé ñóììàðíîé
«ñòîèìîñòüþ» îïåðàöèé (ñ ìèíèìàëüíûì âçâåøåííûì
ðàññòîÿíèåì). Ïðîâåðüòå ïðèâåäåííóþ íèæå ëîãèêó è
óáåäèòåñü (íà êîíêðåòíîì ïðèìåðå), ÷òî â ýòîì ñëó÷àå
âû÷èñëÿåòñÿ êàê âçâåøåííîå ðàññòîÿíèå, òàê è ìàññèâ
óêàçàòåëåé Dp.
Procedure CreateD;
Var i,j,t:Word;
Begin
D[0,0]:=0;
For i:=1 To n Do Begin
D[i,0]:=i*ds;Dp[i,0]:=2; End;
For j:=1 To m Do Begin
D[0,j]:=j*ds;Dp[0,j]:=1; End;
For i:=1 To n Do
For j:=1 To m Do Begin
If S1[i]=S2[j] Then t:=es Else t:=rs;
D[i,j]:=Min(D[i–1,j]+ds,D[i,j–1]+ds,
D[i–1,j–1]+t);
4.1. Îñíîâíîé àëãîðèòì 163
If D[i,j–1]=D[i,j]–ds Then
Dp[i,j]:=Dp[i,j]+1;
If D[i–1,j]=D[i,j]–ds Then
Dp[i,j]:=Dp[i,j]+2;
If D[i–1,j–1]=D[i,j]–t Then
Dp[i,j]:=Dp[i,j]+4;
End;
End;
Ïðèìåð
A = {a, b, c}, S1 = aabbcc, S2 = aacb, Þ
æ 1 -2 -4 -3 ö
ç ÷
ç 3 -1 -2 ÷
rs = ç .
2 -5 ÷
çç ÷÷
è 0 ø
a a b bc c
Âûðàâíèâàíèå èìååò ñóììàðíóþ îöåíêó
a a _ _ cc
Òàáëèöà 4.3
D 0 b c a d a b b d c
0 0 1 2 3 4 5 6 7 8 9
a 1 2 3 2 3 4 5 6 7 8
b 2 1 2 3 4 5 4 5 6 7
c 3 2 1 2 3 4 5 6 7 6
a 4 3 2 1 2 3 4 5 6 7
a 5 4 3 2 3 2 3 4 5 6
d 6 5 4 3 2 3 4 5 4 5
b 7 6 5 4 3 4 3 4 5 6
b 8 7 6 5 4 5 4 3 4 5
d 9 8 7 6 5 6 5 4 3 4
Òàáëèöà 4.4
D 0 f g h i j k
0 0 1 2 3 4 5 6
a 1 2 3 4 5 6 7
b 2 3 4 5 6 7 8
c 3 4 5 6 7 8 9
d 4 5 6 7 8 9 10
e 5 6 7 8 9 10 11
Òàáëèöà 4.5
D 0 a a a a a a
0 0 1 2 3 4 5 6
a 1 0 1 2 3 4 5
a 2 1 0 1 2 3 4
a 3 2 1 0 1 2 3
a 4 3 2 1 0 1 2
a 5 4 3 2 1 0 1
170 Ãëàâà 4. Âû÷èñëåíèå ðàññòîÿíèÿ ìåæäó ñòðîêàìè
Procedure Dist;
Var i,j,d:Integer;
Begin
D[0,0]:=0;
For i:=1 To n Do D[i,0]:=D[i–1,0]+1;
For j:=1 To m Do D[0,j]:=D[0,j–1]+1;
d:=1;
While d<Trail(d) Do d:=2*d;
WriteLn(D[n,m]);
End;
Âðåìÿ âûïîëíåíèÿ ôóíêöèè Trail ñîñòàâëÿåò O(n · d),
à âûïîëíÿåòñÿ îíà äëÿ çíà÷åíèé d, ðàâíûõ 1, 2, … 2t, ãäå t —
íàèìåíüøåå öåëîå, òàêîå, ÷òî d 2t. Ñëåäîâàòåëüíî, îáùåå
âðåìÿ ðàáîòû Trail èìååò òàêóþ æå îöåíêó.
@ Óïðàæíåíèÿ
1. Ïðèâåäèòå ïðèìåð äâóõ ñòðîê. Ïîäñ÷èòàéòå äëÿ íèõ ìàò-
ðèöó D. Ïîñòðîéòå ãðàô G è åãî ñîêðàùåííûé âàðèàíò.
2. Âûïîëíèòå ïðîãðàììíóþ ðåàëèçàöèþ àëãîðèòìà
Ý. Óêêîíåíà è Þ. Ìàéåðñà.
3. Ðàçðàáîòàéòå ìîäèôèêàöèþ àëãîðèòìà Ý. Óêêîíåíà è
Þ. Ìàéåðñà, îáåñïå÷èâàþùóþ íå òîëüêî ïîèñê íàèáîëü-
øåé îáùåé ïîäïîñëåäîâàòåëüíîñòè, íî è âûâîä ñàìîé
ýòîé ïîäïîñëåäîâàòåëüíîñòè.
4. Ïóñòü èçâåñòíà âåðõíÿÿ îöåíêà äëÿ d. Ìîäèôèöèðóéòå
àëãîðèòì Ý. Óêêîíåíà è Þ. Ìàéåðñà äëÿ ýòîãî ñëó÷àÿ.
5. Ïðåäñòàâèì ãðàô, ñîîòâåòñòâóþùèé ñòðîêàì S1 è S2, íå-
ñêîëüêî èíà÷å. Ïóñòü â íåì äèàãîíàëüíîå ðåáðî îò âåðøè-
íû (i – 1, j – 1) ê âåðøèíå (i, j) èäåò òîëüêî â òîì ñëó÷àå,
åñëè S1[i] = S2[j]. Äëÿ ñòðîê S1 = abcaadbbd è
S2 = bcadabbdc òàêîé ãðàô ïðåäñòàâëåí íà ðèñ. 4.3.
Ïóòü äëèíîé L — ýòî ïóòü, ñîäåðæàùèé L âåðøèí ãðàôà
(i1, j1), (i2, j2), ..., (iL, jL), äëÿ êîòîðûõ S1[ik] = S2[jk]
(k = 1..L) è ik–1 < ik, jk–1 < jk. Òîãäà ïðîáëåìà íàõîæäå-
íèÿ íàèáîëüøåé îáùåé ïîäïîñëåäîâàòåëüíîñòè S1 è S2
ýêâèâàëåíòíà íàõîæäåíèþ ïóòè èç âåðøèíû (0, 0) â
âåðøèíó (n, m) íàèáîëüøåé äëèíû èëè ñîäåðæàùåãî íà-
èáîëüøåå êîëè÷åñòâî äèàãîíàëüíûõ ðåáåð. Îáîçíà÷èì
172 Ãëàâà 4. Âû÷èñëåíèå ðàññòîÿíèÿ ìåæäó ñòðîêàìè
Procedure Solve;
Var d,j,x,y:Integer;
Begin
Res[1]:=0;
{Ìàññèâ Res èìååò òèï
TArray=Array[-NMax..NMax] Of Integer;}
For d:=0 To Max(n,m) Do Begin
{Max – ôóíêöèÿ îïðåäåëåíèÿ ìàêñèìàëüíîãî
èç äâóõ ÷èñåë}
For j:=-d To d Do
If (Abs(j) Mod 2)=(d Mod 2) Then Begin
If (j=-d) Or (j<>d) And (Res[j-1]<Res[j+1])
Then x:=Res[j+1]
Else x:=Res[j-1]+1;
y:=x-j;
{Èäåì ïî äèàãîíàëè îò êîíöà ïðåäûäóùåãî
ó÷àñòêà íà äèàãîíàëè j}
While (x<n) And (y<m)
And (S1[x+1]=S2[y+1]) Do
Begin
x:=x+1;
y:=y+1;
End;
Res[j]:=x;
{Çàïîìèíàåì êîíåö äèàãîíàëüíîãî ó÷àñòêà}
If (x>=n) And (y>=m) Then Begin
WriteLn(d); {WriteLn(Max(n,m)-d);}
Exit;
End;
End;
End;
End;
174 Ãëàâà 4. Âû÷èñëåíèå ðàññòîÿíèÿ ìåæäó ñòðîêàìè
Òàáëèöà 4.6
Íîìåð
V 0 1 2 3 4 5 6 7 8 9
ñèìâîëà
Íîìåð
Ñèìâîë a b c a a d b b d
ñèìâîëà
0 0 0 0 0 0 0 0 0 0 0
1 b 0 0 1 1 1 1 1 1 1 1
2 c 0 0 1 2 2 2 2 2 2 2
3 a 0 1 1 2 3 3 3 3 3 3
4 d 0 1 1 2 3 3 4 4 4 4
5 a 0 1 1 2 3 4 4 4 4 4
6 b 0 1 2 2 3 4 4 5 5 5
7 b 0 1 2 2 3 4 4 5 6 6
8 d 0 1 2 2 3 4 5 5 6 7
9 c 0 1 2 3 3 4 5 5 6 7
176 Ãëàâà 4. Âû÷èñëåíèå ðàññòîÿíèÿ ìåæäó ñòðîêàìè
Òàáëèöà 4.7
Íîìåð
V 0 1 2 3 4 5 6 7 8 9
ñèìâîëà
Íîìåð
Ñèìâîë b c a d a b b d c
ñèìâîëà
0 0 0 0 0 0 0 0 0 0 0
1 a 0 0 0 1 1 1 1 1 1 1
2 b 0 1 1 1 1 1 2 2 2 2
3 c 0 1 2 2 2 2 2 2 2 3
4 a 0 1 2 3 3 3 3 3 3 3
Òàáëèöà 4.8
Íîìåð
V 0 1 2 3 4 5 6 7 8 9
ñèìâîëà
Íîìåð
Ñèìâîë b c a d a b b d c
ñèìâîëà
0 0 0 0 0 0 0 0 0 0 0
1 a 0 0 0 1 1 1 1 1 1 1
2 d 0 0 0 1 2 2 2 2 2 2
3 b 0 1 1 1 2 2 3 3 3 3
4 b 0 1 1 1 2 2 3 4 4 4
5 d 0 1 1 1 2 2 3 4 5 5
Òàáëèöà 4.9
b c a d a b b d c
a __ b __ c a
a b __ __ c a
a __ __ __ b __ c a
a __ __ b __ __ c a
a b c __ __ a
a b c a
1)
 êíèãå Á. Ñìèòà (ñ. 288–291) äîêàçûâàåòñÿ (ëåììû, òåîðåìà) ïðàâèëüíîñòü
äàííîãî ðåçóëüòàòà, íî íàñ èíòåðåñóåò íå êîíå÷íûé ðåçóëüòàò êàê òàêîâîé,
îôîðìëåííûé äîêàçàòåëüíî, à ïðîöåññ åãî «ðîæäåíèÿ» (ïðåäïîëàãàåìûé)
ó ñïåöèàëèñòà ïî èíôîðìàòèêå. Ìîæíî ñ îïðåäåëåííîé äîëåé óâåðåííîñòè
óòâåðæäàòü, ÷òî ëåììû è òåîðåìû îôîðìëÿþòñÿ óæå ïîñëå åãî ïîëó÷åíèÿ
(è íå âñåãäà óäà÷íî).
180 Ãëàâà 4. Âû÷èñëåíèå ðàññòîÿíèÿ ìåæäó ñòðîêàìè
@ Óïðàæíåíèÿ
1. Ïðèâåäèòå ïðèìåðû äâóõ ñòðîê è âû÷èñëèòå âðó÷íóþ
äëèíó èõ íàèáîëüøåé îáùåé ïîäïîñëåäîâàòåëüíîñòè.
Âûïîëíèòå îáðàòíûé ïðîñìîòð ïî çíà÷åíèÿì èç V è íàé-
äèòå âñå lcs (åñëè èõ íåñêîëüêî).
2. Èñêëþ÷èì â ðàññòîÿíèè Â. Ëåâåíøòåéíà îïåðàöèþ ïîä-
ñòàíîâêè Re. Òî÷íåå, áóäåì ñ÷èòàòü, ÷òî ýòà îïåðàöèÿ
èìååò âåñ 2 è âûïîëíÿåòñÿ ïóòåì óäàëåíèÿ ñèìâîëà èç
S1 è ïîñëåäóþùåé âñòàâêè ñèìâîëà, ðàâíîãî ñîîòâåò-
ñòâóþùåìó ñèìâîëó èç S2. Ïîêàæèòå, ÷òî â ýòîì ñëó÷àå
d(S1, S2) = n + m – 2 · lcs(S1, S2).
3. Äîïîëíèòå ëîãèêó âû÷èñëåíèÿ äëèíû íàèáîëüøåé îá-
ùåé ïîäïîñëåäîâàòåëüíîñòè S1 è S2 âû÷èñëåíèåì ìàññè-
âà óêàçàòåëåé è ïîñëåäóþùèì âûâîäîì âñåõ lcs(S1, S2).
4. Èññëåäóéòå âîçìîæíîñòü äîâåäåíèÿ ðåêóðñèâíîé ñõåìû
âû÷èñëåíèÿ lcs äî ðàáîòîñïîñîáíîãî ñîñòîÿíèÿ.
Procedure Build;
Var i,j,q,t:Integer;
Begin
t:=1;
For i:=1 To n Do Begin
For j:=m DownTo 1 Do
{Ñêàíèðóåì âòîðóþ ñòðîêó â îáðàòíîì íàïðàâëåíèè.
 ìàññèâå V èùóòñÿ èíäåêñû j, óäîâëåòâîðÿþùèå
óñëîâèþ: V[i–1,q–1]<jm<jm–1<...<j1<V[i–1,q]}
If S1[i]=S2[j] Then Begin
q:=Find(V[i-1],j);
{Ïîèñê "ñàìîãî ëåâîãî" èíäåêñà,
óäîâëåòâîðÿþùåãî óñëîâèþ}
If q<>0 Then Begin V[i,q]:=j; t:=q; End;
{Çàïîìèíàåì çíà÷åíèå q, òàê êàê â ýòîé ñòðîêå
ïîòðåáóåòñÿ êîððåêòèðîâêà çíà÷åíèé (ïóòåì
ïåðåïèñûâàíèÿ èç ïðåäûäóùåé ñòðîêè) V
ñ ìåíüøèìè èíäåêñàìè}
End;
184 Ãëàâà 4. Âû÷èñëåíèå ðàññòîÿíèÿ ìåæäó ñòðîêàìè
Function Build:Integer;
Var i,j,q,t:Integer;
p:PListEl;
Begin
t:=1;
For i:=1 To n Do Begin
p:=AListEl[Byte(S1[i])];
{Ôóíêöèÿ Byte ïðåîáðàçóåò ñèìâîë â åãî äâîè÷íîå
ïðåäñòàâëåíèå — ÷èñëî. Ñïèñêè íîìåðîâ ïîçèöèé
ñèìâîëîâ â S2 îðãàíèçîâàíû â óáûâàþùåì ïîðÿäêå}
While p<>Nil Do Begin
q:=Find(V[i-1],p^.x);
If q>0 Then Begin V[i,q]:=p^.x; t:=q; End;
p:=p^.next;
End;
For j:=1 To t-1 Do
If V[i,j]>=m Then V[i,j]:=V[i-1,j];
End;
Build:=t-1;
End;
Âðåìÿ ðàáîòû òàêîãî àëãîðèòìà óìåíüøàåòñÿ ñ îöåíêè
O(n · m) äî O(n + r), ãäå r — êîëè÷åñòâî ïàð ñîâïàäàþùèõ
ñèìâîëîâ â S1 è S2. Îäíàêî åñòü åùå êîíñòðóêöèÿ
For j:=1 To t-1 Do
If V[i,j]>=m Then V[i,j]:=V[i-1,j];.
1)
Îêóëîâ Ñ. Ì. Ðàçâèòèå èíòåëëåêòà øêîëüíèêà. Àáñòðàêòíûå òèïû äàí-
íûõ. — Ì.:ÁÈÍÎÌ. Ëàáîðàòîðèÿ çíàíèé, 2009.
188 Ãëàâà 4. Âû÷èñëåíèå ðàññòîÿíèÿ ìåæäó ñòðîêàìè
i:=temp^.xv;
j:=temp^.yv;
lcs:=S1[i]+lcs;
ln:=ln-1;
End;
temp:=temp^.next;
End;
End;
Âðåìåííàÿ îöåíêà ðàáîòû îïèìèçèðîâàííîãî âàðèàíòà
àëãîðèòìà èìååò âèä O((n + r) · log2q), ãäå n — äëèíà ìåíü-
øåé ñòðîêè, r — êîëè÷åñòâî ñîâïàäàþùèõ ñèìâîëîâ, à q —
êîëè÷åñòâî ñèìâîëîâ â îáùåé ïîäïîñëåäîâàòåëüíîñòè íàè-
áîëüøåé äëèíû.
@ Óïðàæíåíèÿ
1. Ïðèâåäèòå ïðèìåðû äâóõ ñòðîê. Ïóòåì ôîðìèðîâàíèÿ
ìàññèâà V ïîäñ÷èòàéòå äëÿ íèõ äëèíó íàèáîëüøåé îá-
ùåé ïîäïîñëåäîâàòåëüíîñòè.
2. Ïóòåì îáðàòíîãî ïðîñìîòðà ýëåìåíòîâ V âûïèøèòå íàè-
áîëüøóþ îáùóþ ïîäïîñëåäîâàòåëüíîñòü ñòðîê.
3. Ðàçðàáîòàéòå ïðîãðàììíóþ ðåàëèçàöèþ àëãîðèòìà
Ä. Õàíòà è Ò. Çèìàíñêîãî (íåîïòèìèçèðîâàííûé âàðèàíò).
4. Äàíà ñòðîêà S. Ðàçðàáîòàéòå ïðîãðàììó ôîðìèðîâàíèÿ
ñïèñêîâ èç íîìåðîâ ïîçèöèé ñ îäèíàêîâûìè ñèìâîëàìè
ñòðîêè.
5. Ðàçðàáîòàéòå ïðîãðàììíóþ ðåàëèçàöèþ àëãîðèòìà
Ä. Õàíòà è Ò. Çèìàíñêîãî (îïòèìèçèðîâàííûé âàðèàíò).
Îöåíèòå âðåìÿ ðàáîòû â íàèõóäøåì è íàèëó÷øåì ñëó-
ֈ؛.
Ïðèìåð
Àëôàâèò À ñîñòîèò èç ñèìâîëîâ {a, b, c, d}. Äàíû ñòðîêè
S1 = bcadabbdc, S2 = abcaadbbd. Òðåáóåòñÿ íàéòè äëèíó
íàèáîëüøåé îáùåé ïîäïîñëåäîâàòåëüíîñòè ýòèõ ñòðîê.
 òàáë. 4.10 ïðåäñòàâëåíû õàðàêòåðèñòè÷åñêèå âåêòîðû
äëèíîé n áèò, îïèñûâàþùèå âõîæäåíèå ñèìâîëîâ â S1 (ìàò-
ðèöà V).
Òàáëèöà 4.10
V b c a d a b b d c
a 0 0 1 0 1 0 0 0 0
b 1 0 0 0 0 1 1 0 0
c 0 1 0 0 0 0 0 0 1
d 0 0 0 1 0 0 0 1 0
Òàáëèöà 4.11
V[a] 0 0 1 0 1 0 0 0 0
Åäèíèöà 0 0 0 0 0 0 0 0 1
Âû÷èòàíèå: V[a] – 1 0 0 1 0 0 1 1 1 1
(V[a] – 1) Xor V[a] 0 0 0 0 1 1 1 1 1
((V[a] – 1) Xor V[a]) And V[a] 0 0 0 0 1 0 0 0 0
Òàáëèöà 4.12
R Äåéñòâèå Ðàçðÿäû
R[4] x = V[a] Or R[5] 1 1 1 1 1
t = R[5]¬ íà 1ðàçðÿä+1 0 0 0 0 1
x–t 1 1 1 1 0
x Xor (x – t) 0 0 0 0 1
x And (x Xor (x – t)) 0 0 0 0 1
R[3] x = V[a] Or R[4] 1 1 1 1 1
t = R[4]¬ íà 1ðàçðÿä + 1 0 0 0 1 1
x–t 1 1 1 0 0
x Xor (x – t) 0 0 0 1 1
x And (x Xor (x – t)) 0 0 0 1 1
R[2] x = V[a] Or R[3] 1 1 1 1 1
t = R[3]¬ íà 1ðàçðÿä + 1 0 0 1 1 1
x–t 1 1 0 0 0
x Xor (x – t) 0 0 1 1 1
x And (x Xor (x – t)) 0 0 1 1 1
R[1] x = V[a] Or R[2] 1 1 1 1 1
t = R[2]¬ íà 1ðàçðÿä + 1 0 1 1 1 1
x–t 1 0 0 0 0
x Xor (x – t) 0 1 1 1 1
x And (x Xor (x – t)) 0 1 1 1 1
192 Ãëàâà 4. Âû÷èñëåíèå ðàññòîÿíèÿ ìåæäó ñòðîêàìè
æ0 1 1 1 1ö
ç ÷
ç0 0 1 1 1÷
Òàêèì îáðàçîì, R = ç . Â ñòðîêå R[4] îäíà
0 0 0 1 1÷
çç ÷÷
è0 0 0 0 1ø
åäèíèöà, è îíà ãîâîðèò î òîì, ÷òî ñóôôèêñû a ñòðîê S2 è S1
èìåþò lcs äëèíû 1 è óêàçûâàåòñÿ ñàìîå ïðàâîå âõîæäåíèå
lcs. Àíàëîãè÷íî — äëÿ ñòðîê R[3] è R[2]. Êîëè÷åñòâî æå åäè-
íèö â R[1] äàåò äëèíó lcs äëÿ ñòðîê S1 è S2.
Ðàññìîòðèì åùå îäèí ïðèìåð. Ïóñòü R[i] = 000110010,
à î÷åðåäíûì, (i – 1)-ì ñèìâîëîì S2 ÿâëÿåòñÿ ñèìâîë b (åãî
õàðàêòåðèñòè÷åñêèé âåêòîð — 100001100). Ðàçäåëèì R[i]
íà áëîêè (ðàçäåëèòåëü îáîçíà÷åí ñèìâîëîì «»)
000110010 ïî ñëåäóþùåìó ïðàâèëó: èäåì ïî ñòðîêå ñëå-
âà íàïðàâî; áëîê çàêàí÷èâàåòñÿ ïåðåä ïåðâîé åäèíèöåé
ñïðàâà (óñëîâíî ñ÷èòàåì, ÷òî ñòðîêà R âñåãäà íà÷èíàåòñÿ ñ
åäèíèöû — íóëåâîé ñòîëáåö), à ñëåäóþùèé íà÷èíàåòñÿ ñ
ýòîé åäèíèöû; áëîê ìîæåò çàêîí÷èòüñÿ íóëåì, åñëè îí —
ïîñëåäíèé â ñòðîêå. Îáúåäèíåíèåì R[i] c V[b] ñ ïîìîùüþ
îïåðàöèè Or ôèêñèðóåòñÿ ïðèñóòñòâèå ñèìâîëîâ b â êàæäîì
áëîêå: x = R[i] Or V[b] = 100111110. Ñäâèã íà îäèí ðàçðÿä
âëåâî ñòðîêè R[i] è äîáàâëåíèå åäèíèöû ê ìëàäøåìó ðàçðÿ-
äó (t = R[i] ¬1 ðàçðÿä + 1 = 001100101) ñîõðàíÿåò ñòðóêòóðó
ðàçáèåíèÿ ñòðîêè íà áëîêè è ââîäèò îäèí (âîçìîæíûé) áëîê
â ñëåäóþùåé R[i – 1]-é ñòðîêå. Îñòàëüíûå îïåðàöèè: ((x – t)
Xor x) And x = ((100111110 – 001100101) Xor 100111110) And
100111110 = 100100110 — ðåøàþò çàäà÷ó ôèêñàöèè
ñòàðøåé åäèíèöû, íî óæå â êàæäîì áëîêå. Ñòðîêà R[i – 1]
ñîäåðæèò ÷åòûðå åäèíèöû, ò. å. ó ñóôôèêñà S2[i – 1..m] è S1
ñóùåñòâóåò lcs äëèíû 4 (îáðàòèòå âíèìàíèå, ÷òî çäåñü íå ãî-
âîðèòñÿ î òîì, èç êàêèõ ñèìâîëîâ ñîñòîèò lcs, — ãîâîðèòñÿ
ëèøü î òîì, ÷òî îíà ñîñòîèò èç ÷åòûðåõ ñèìâîëîâ!).
Îáðàòèìñÿ âíîâü ê íàøåìó ñêâîçíîìó ïðèìåðó. Îêîí÷à-
òåëüíûé âèä ìàòðèöû R ïðèâåäåí â òàáë. 4.13.
Ïóñòü ôîðìèðóåòñÿ R[4]. Èìååì: R[5] = 001011110
(ðàçäåëèëè íà áëîêè), à õàðàêòåðèñòè÷åñêèé âåêòîð ñèìâî-
ëà a ðàâåí 001010000. Ëîãè÷åñêàÿ ñóììà ðàâíà
x = 001011110. Çíà÷åíèå R[5], ñäâèíóòîå íà îäèí ðàçðÿä
âëåâî ñ ïðèáàâëåíèåì åäèíèöû, ðàâíî 010111101. Ðàçíîñòü
t = 110100001 (îáðàòèòå âíèìàíèå, ÷òî ïðèøëîñü çàèìñòâî-
4.3. Çàäà÷à î íàèáîëüøåé îáùåé ïîäïîñëåäîâàòåëüíîñòè 193
Òàáëèöà 4.13
R S1 b c a d a b b d c
S2 i/j 0 1 2 3 4 5 6 7 8 9
a 1 1 1 1 1 0 1 1 1 0 1
b 2 1 1 1 1 0 1 1 1 0 1
c 3 1 0 1 1 0 1 1 1 0 1
a 4 1 0 0 1 0 1 1 1 1 0
a 5 1 0 0 1 0 1 1 1 1 0
d 6 1 0 0 0 1 0 1 1 1 0
b 7 1 0 0 0 0 0 1 1 1 0
b 8 1 0 0 0 0 0 0 1 1 0
d 9 1 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0
@ Óïðàæíåíèÿ
1. Äëÿ ñòðîê S1 = tgcctaag è S2 = gctacctc óáåäèòåñü,
÷òî ìàòðèöà R èìååò âèä:
æ0 1 0 1 1 0 0 1 ö
ç ÷
ç1 0 0 1 1 0 1 0 ÷
ç1 0 1 0 1 0 1 0 ÷
ç ÷
ç0 0 1 1 0 0 1 0÷
R =ç ,
0 0 1 1 0 0 1 0÷
ç ÷
ç0 0 0 1 1 0 0 0÷
ç ÷
ç1 0 0 0 1 0 0 0 ÷
ç0 0 0 1 0 0 0 0÷
è ø
4.3. Çàäà÷à î íàèáîëüøåé îáùåé ïîäïîñëåäîâàòåëüíîñòè 195
Ìåòîäè÷åñêèé êîììåíòàðèé
Àëãîðèòìû âû÷èñëåíèÿ ðàññòîÿíèÿ ìåæäó ñòðîêàìè è íà-
õîæäåíèÿ ïîäïîñëåäîâàòåëüíîñòåé ÿâëÿþòñÿ, åñëè òàê ìîæíî
âûðàçèòüñÿ, «ïðåàìáóëîé» ê öåëîìó êëàññó àëãîðèòìîâ ïðè-
áëèæåííîãî ñîïîñòàâëåíèÿ ñòðîê. Ïîñëåäíèå èìåþò îãðîìíîå
çíà÷åíèå êàê â ìîëåêóëÿðíîé áèîëîãèè, òàê è â äðóãèõ îáëàñ-
òÿõ çíàíèÿ, âêëþ÷àÿ computer science.
Àëãîðèòì íàõîæäåíèÿ ðàññòîÿíèÿ ìåæäó ñòðîêàìè äîñòà-
òî÷íî èçâåñòåí, õîòÿ åãî îïèñàíèå ìîæíî âñòðåòèòü íå òàê ÷àñ-
òî (â ñèëó åãî ïðîñòîòû è î÷åâèäíîñòè). Á. Ñìèò íàçûâàåò åãî
«àëãîðèòìîì Ð. Âàãíåðà (Robert Wagner) è Ì. Ôèøåðà
(Michael Fischer)». Ïðîñòîé àëãîðèòì íàõîæäåíèÿ íàèáîëü-
øåé îáùåé ïîäïîñëåäîâàòåëüíîñòè ïðèïèñûâàþò ðàçëè÷íûì
àâòîðàì, íî íà ðóññêîì ÿçûêå îí ñòàë èçâåñòåí êàê «àëãîðèòì
Ñ. Íóäåëüìàíà (Saul Needleman) – Ê. Âóíøà (Chris-
tian Wunsch)»1). Åãî èçìåíåíèÿ, íàïðàâëåííûå íà óìåíüøå-
íèå îáúåìà èñïîëüçóåìîé ïàìÿòè, îïðåäåëÿþò êàê àëãîðèòì
1)
Needleman Saul B., Wunsch Christian D. A general method applicable to the
search for similarities in the amino–acid principle of two proteins //
J. Molecular Biology 48, 1970. P. 443–453.
4.3. Çàäà÷à î íàèáîëüøåé îáùåé ïîäïîñëåäîâàòåëüíîñòè 197
1)
Hirschberg Dan S. Algorithms for the longest common subsequence problem //
JACM 24–4, 1977. P. 664–675.
2)
Hynt James W., Szymancki Thomas G. A fast algorithm for computing longest
common subsequences // CACM 20–5, 1977. P. 350–353.
3)
Ukkonen Esko. Algorithms for approximate string matching // Information &
Control, 64, 1985. P. 100–118.
4)
Myers Gene W. An O(ND) difference algorithm and its variations //
Algorithmica I, 1986. P. 251–266.
5)
Allison Lloyd, Dix Trevor. A bit string longest subsequence algorithm // IPL,
23–6, 1986. P. 305–310.
6)
Crochemore Maxime, Iliopoulos Costas, Pinzon Yoan. Speeding up Hirschberg
and Hunt–Szymancki LCS algorithms // Proc. Eighth IEEE Internal. Symp.
String Processing & Information Retrieval. IEEE Computer Science Press,
2001. P. 59–67.
Ãëàâà 5
Àëãîðèòìû ïðèáëèæåííîãî
ïîèñêà ïîäñòðîê
Îïðåäåëèì çàâèñèìîñòè:
l D[0, 0] = 0 — ïóñòàÿ ñòðîêà ïðåîáðàçóåòñÿ â ïóñòóþ
ñòðîêó çà íóëü îïåðàöèé;
l D[0, j] = j äëÿ j îò 1 äî m — ïóñòàÿ ñòðîêà ïðåîáðàçó-
åòñÿ â ïðåôèêñ P[1..j] çà j îïåðàöèé âñòàâêè, è ýòî ìè-
íèìàëüíîå êîëè÷åñòâî îïåðàöèé;
l D[i, 1] = min(D[i – 1,1] + 1, D[T[i], P[j]]) — èùåòñÿ
ìèíèìàëüíîå ðàññòîÿíèå ìåæäó P[1] è ïîäñòðîêîé
T[i¢, i]. Åñëè T[i] = P[j], òî D[T[i], P[j]] = 0; ïðè
T[i] ¹ P[j] ìû èìååì D[T[i], P[j]] = 2.
Ðåêóððåíòíîå ñîîòíîøåíèå äëÿ D[i, j] ïðè 1 i n è
1 < j m èìååò âèä:
D[i, j] = min{D[i – 1, j] + 1, D[i, j – 1] + 1, D[i – 1, j – 1] + t},
ãäå t = 2, åñëè T[i] ¹ P[j], è t = 0, åñëè T[i] = P[j].
Ïîñëå âû÷èñëåíèÿ ìàññèâà ðàññòîÿíèé D äëÿ ëþáîãî íå-
îòðèöàòåëüíîãî öåëîãî ÷èñëà k è ïðåôèêñà P[1..j] ó íàñ åñòü
âîçìîæíîñòü îòâåòèòü íà âîïðîñ î òîì, âõîäèò ëè P[1..j] â T
ñ òî÷íîñòüþ äî k îïåðàöèé ðåäàêòèðîâàíèÿ (k-ïðèáëèæåí-
íîå âõîæäåíèå P â T). Äëÿ ýòîãî äîñòàòî÷íî ïðîñìîòðåòü
ñòîëáåö j è íàéòè çíà÷åíèÿ D[i, j] k. Íàéäåííîå çíà÷åíèå
D[i, j] ãîâîðèò î òîì, ÷òî ñóùåñòâóåò ïîäñòðîêà T[i¢..i], îòëè-
÷àþùàÿñÿ îò P[1..j] íå áîëåå ÷åì íà çíà÷åíèå k (k-ïðèáëèæå-
íèå). Èëè, äðóãèìè ñëîâàìè, ýòà ïîäñòðîêà è ïðåôèêñ
P[1..j] ìîãóò áûòü ïðåîáðàçîâàíû äðóã â äðóãà îïåðàöèÿìè
ðåäàêòèðîâàíèÿ ñ ñóììàðíûì âåñîì íå áîëåå ÷åì k.
Ïðèìåð
Ïóñòü T = abcaadbbd è P = bcadab. Ïîëó÷àåìûé äëÿ
íèõ ìàññèâ D ïðåäñòàâëåí â òàáë. 5.1.
Âîçüìåì ïðåôèêñ P[1..4] = bcad. Ïðîàíàëèçèðóåì äàí-
íûå èç ñòîëáöà ¹ 4:
l T[1..1] = a — âñòàâêà òðåõ ñèìâîëîâ;
l T[1..2] = ab — ïîäñòðîêà b, âñòàâêà òðåõ ñèìâîëîâ;
l T[1..3] = abc — ïîäñòðîêà bc, âñòàâêà äâóõ ñèìâîëîâ;
l T[1..4] = abca — ïîäñòðîêà bca, âñòàâêà îäíîãî ñèì-
âîëà;
l T[1..5] = abcaa — ïîäñòðîêà bcaa, ïîäñòàíîâêà îäíî-
ãî ñèìâîëà;
l T[1..6] = abcaad — ïîäñòðîêà bcaad, óäàëåíèå îäíîãî
ñèìâîëà a;
200 Ãëàâà 5. Àëãîðèòìû ïðèáëèæåííîãî ïîèñêà ïîäñòðîê
Òàáëèöà 5.1
Íîìåð
D 1 2 3 4 5 6
ñèìâîëà
Íîìåð
Ñèìâîë b c a d a b
ñèìâîëà
0 Ñèìâîë 1 2 3 4 5 6
1 a 2 3 2 3 4 5
2 b 0 1 2 3 4 4
3 c 1 0 1 2 3 4
4 a 2 1 0 1 2 3
5 a 2 2 1 2 1 2
6 d 2 3 2 1 2 3
7 b 0 1 2 2 3 2
8 b 0 1 2 3 4 3
9 d 1 2 3 2 3 4
@ Óïðàæíåíèÿ
1. Ïðèâåäèòå ïðèìåðû ñòðîê P è T. Âû÷èñëèòå äëÿ íèõ
ìàòðèöó ðàññòîÿíèé D. Äëÿ êàæäîãî ïðåôèêñà P îïðå-
äåëèòå ïîäñòðîêó T, íà êîòîðîé äîñòèãàåòñÿ ïîëó÷åííàÿ
îöåíêà.
2. Ðàçðàáîòàéòå ïðîãðàììó ôîðìèðîâàíèÿ ìàññèâà D è ïî-
èñêà òàêîãî çíà÷åíèÿ i¢, ÷òî d(T[i¢..n], P) = D[n, m].
3. Äëÿ çàäàííîãî çíà÷åíèÿ k íàéäèòå âñå òàêèå çíà÷åíèÿ
i¢ è i, ÷òî d(T[i¢..i], P) k.
Ïðèìåð
Ïóñòü P = bacaba, T = abcdabd è k = 3. Ïðèâåäåì ìàò-
ðèöó D (òàáë. 5.2), íî òîëüêî äëÿ ïîíèìàíèÿ èäåéíîé îñíî-
âû àëãîðèòìà.
202 Ãëàâà 5. Àëãîðèòìû ïðèáëèæåííîãî ïîèñêà ïîäñòðîê
Òàáëèöà 5.2
D b a c a b a
a 2 1 2 3 4 5
b 0 1 2 3 3 4
c 1 2 1 2 3 4
d 2 3 2 3 4 5
b 0 1 2 3 3 4
a 1 0 1 2 3 3
d 2 1 2 3 4 4
Òàáëèöà 5.3
R0 R1 R2 R3
b a c a b a b a c a b a b a c a b a b a c a b a
a 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 1 1 1 0 0 0 0 1 1
b 0 1 1 1 1 1 0 0 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 1
c 1 1 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 1 0 0 0 0 0 1
d 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 1
b 0 1 1 1 1 1 0 0 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 1
a 1 0 1 1 1 1 0 0 0 1 1 1 0 0 0 0 1 1 0 0 0 0 0 0
d 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 1 1 1 0 0 0 0 1 1
Òàáëèöà 5.4
V b a c a b a
a 1 0 1 0 1 0
b 0 1 1 1 0 1
c 1 1 0 1 1 1
d 1 1 1 1 1 1
@ Óïðàæíåíèÿ
1. Ïðèâåäèòå ïðèìåð P è T. Âû÷èñëèòå âõîæäåíèå P â Ò ñ
òî÷íîñòüþ äî òðåõ íåñîâïàäåíèé.
2. Ïóñòü îïåðàöèÿ âñòàâêè èìååò âåñ 2, îïåðàöèÿ óäàëå-
íèÿ — âåñ 3, à îïåðàöèÿ çàìåíû — òàêæå âåñ 3. Ïðîàíà-
ëèçèðóéòå ðàáîòó àëãîðèòìà Ñ. Âó – Þ. Ìåíáåðà äëÿ ýòî-
ãî ñëó÷àÿ ïóòåì ïîýòàïíîãî âû÷èñëåíèÿ áèíàðíûõ
âåêòîðîâ ïðè êîíêðåòíûõ çíà÷åíèÿõ P è T.
3. Ðàçðàáîòàéòå ïðîãðàììíóþ ðåàëèçàöèþ àëãîðèòìà
Ñ. Âó – Þ. Ìåíáåðà.
Òàáëèöà 5.5
V b a c a b a
a 01 00 01 00 01 00
b 00 01 01 01 00 01
c 01 01 00 01 01 01
d 01 01 01 01 01 01
Ïðèìåð
P = bacaba, T = badabaacbabaca, k = 3. Îáðàçåö P âõî-
äèò â ïîäñòðîêó:
l badaba — ñ îäíèì íåñîâïàäåíèåì;
l baacba — ñ äâóìÿ íåñîâïàäåíèÿìè;
l acbaba — ñ òðåìÿ íåñîâïàäåíèÿìè;
l babaca — ñ äâóìÿ íåñîâïàäåíèÿìè.
Òàáëèöà 5.6
Òàáëèöà 5.7
Íîìåð
b a d a b a a c b a b a c a pc 1 2 3 4 cnt
øàãà
0 b a c a b a 0 3 7 7 7 1
1 b a c a b a 1 1 2 3 4 4
2 b a c a b a 2 1 3 5 6 4
3 b a c a b a 3 1 2 3 5 4
4 b a c a b a 4 3 4 7 7 2
5 b a c a b a 5 1 4 5 6 4
6 b a c a b a 6 1 2 3 7 3
7 b a c a b a 7 1 2 3 4 4
8 b a c a b a 8 3 5 7 7 2
Òàáëèöà 5.8
Òàáëèöà 5.9
À B Êîììåíòàðèé
= = Ñîâïàäåíèå; ïîçèöèè q íåò â ìàòðèöàõ pc è pn. Ïåðå-
õîä ê ñëåäóþùåìó çíà÷åíèþ q
= ¹ Íåñîâïàäåíèå; ïîçèöèè q íåò â pc, íî îíà åñòü â pn. Íî-
ìåð ïîçèöèè q ñëåäóåò çàïèñàòü â pc[i, cnt]
¹ = Íåñîâïàäåíèå; ïîçèöèÿ q åñòü â pc, íî åå íåò â pn. Íî-
ìåð ïîçèöèè q ñëåäóåò çàïèñàòü â pc[i, cnt]
¹ ¹ Íåîïðåäåëåííîñòü. Òðåáóåòñÿ ñðàâíåíèå ñèìâîëîâ
P[q] è T[i + q + 1], ïî ðåçóëüòàòàì êîòîðîãî ïðèíèìà-
åòñÿ ðåøåíèå
@ Óïðàæíåíèÿ
1. Ïðèâåäèòå ïðèìåðû ñòðîê P è T, çàäàéòå èõ çíà÷åíèå k
è âûïîëíèòå ðó÷íóþ òðàññèðîâêó ðàáîòû ìîäèôèöèðî-
âàííîãî àëãîðèòìà Shift-And ïîèñêà k-íåñîâïàäåíèé (ïî
òèïó òàáë. 5.6).
2. Ðàçðàáîòàéòå ïðîãðàììíóþ ðåàëèçàöèþ ìîäèôèöèðî-
âàííîãî àëãîðèòìà Shift-And ñ âðåìåííîé îöåíêîé O(n).
3. Çàäàéòå çíà÷åíèÿ P, T è k. Ïðîöåäóðà Extend àëãîðèòìà
Ã. Ëàíäàó – Þ. Âèøêèíà âûçûâàåòñÿ ñ îïðåäåëåííûìè
ïàðàìåòðàìè. Óêàæèòå òî ìåñòî òåêñòà, ñ êîòîðîãî áóäåò
ïðîèñõîäèòü ñðàâíåíèå ñèìâîëîâ.
4. Ïóñòü P = am è T = an (n > m). Ïðîàíàëèçèðóéòå ðàáîòó
îáîèõ ðàññìîòðåííûõ àëãîðèòìîâ ïðè ýòèõ èñõîäíûõ
äàííûõ.
5. Ïóñòü â P íåò ïîâòîðÿþùèõñÿ ñèìâîëîâ è íè îäèí ñèì-
âîë èç P íå ñîâïàäàåò ñ ñèìâîëàìè èç T (ò. å. P è T ñîñòî-
ÿò èç ðàçíûõ ñèìâîëîâ). Ïðîàíàëèçèðóéòå ðàáîòó ðàñ-
ñìîòðåííûõ àëãîðèòìîâ ïðè ýòèõ èñõîäíûõ äàííûõ.
6. Çàäàéòå çíà÷åíèÿ P, T è k. Áåç èñïîëüçîâàíèÿ ïðîãðàì-
ìíîãî êîäà àëãîðèòìà Ã. Ëàíäàó – Þ. Âèøêèíà ñîñòàâü-
òå äèàãðàììó ñðàáàòûâàíèé ïðîöåäóð Extend è Merge
(ïî òèïó ïðèâåäåííîé íà ðèñ. 5.2).
7. Ðàçðàáîòàéòå ïðîãðàììíóþ ðåàëèçàöèþ àëãîðèòìà
Ã. Ëàíäàó – Þ. Âèøêèíà.
1)
Èçëîæåíèå ìàêñèìàëüíî ïðèáëèæåííî ê òåêñòó êíèãè Á. Ñìèòà (ñ. 325–332)
ïî ïðè÷èíå, êîòîðàÿ ñòàíåò ÿñíà â êîíöå ýòîãî ðàçäåëà.
216 Ãëàâà 5. Àëãîðèòìû ïðèáëèæåííîãî ïîèñêà ïîäñòðîê
Ïðèìåð
S1 = aabcab (m = |S1|), S2 = caabb (n = |S2|).
Ââåäåì ìàòðèöó V:
ì1, ïðè S1 [i] ¹ S2 [j],
V [i, j] = í
î0, ïðè S1 [i] = S2 [j].
Äëÿ S1 è S2 îíà ïðèâåäåíà â òàáë. 5.10.
Òàáëèöà 5.10
V a a b c a b
c 1 1 1 0 1 1
a 0 0 1 1 1 1
a 0 0 1 1 1 1
b 1 1 0 1 1 0
b 1 1 0 1 1 0
Òàáëèöà 5.11
D a a b c a b
0 1 2 3 4 5 6
c 1 1 2 3 3 4 5
a 2 1 1 2 3 3 4
a 3 2 1 2 3 3 4
b 4 3 2 1 2 3 3
b 5 4 3 2 2 3 3
Òàáëèöà 5.12
D a a b c a b
0 1 1 1 1 1 1
c 0 0 1 1 1 1 1
a 0 –1 0 1 1 0 1
a 0 –1 –1 1 1 0 1
b 0 –1 –1 –1 1 1 0
b 0 –1 –1 –1 0 1 0
Òàáëèöà 5.13
D¢ a a b c a b
0 0 0 0 0 0 0
c 1 0 0 0 –1 –1 –1
a 1 0 –1 –1 0 –1 –1
a 1 1 0 0 0 0 0
b 1 0 1 –1 –1 0 –1
b 1 1 1 1 0 0 0
Òàáëèöà 5.14
P a a b c a b
c 0 1 1 1 1 1
a 0 0 1 1 0 1
a 0 0 1 1 0 1
b 0 0 0 1 1 0
b 0 0 0 0 1 0
Òàáëèöà 5.15
P’ a a b c a b
c 0 0 0 0 0 0
a 0 0 0 0 0 0
a 1 0 0 0 0 0
b 0 1 0 0 0 0
b 1 1 1 0 0 0
5.4. Àëãîðèòì Þ. Ìàéåðñà 219
Òàáëèöà 5.16
M a a b c a b
c 0 0 0 0 0 0
a 1 0 0 0 0 0
a 1 1 0 0 0 0
b 1 1 1 0 0 0
b 1 1 1 0 0 0
Òàáëèöà 5.17
M¢ a a b c a b
c 0 0 0 1 1 1
a 0 1 1 0 1 1
a 0 0 0 0 0 0
b 0 0 1 1 0 1
b 0 0 0 0 0 0
Òàáëèöà 5.18
Òàáëèöà 5.19
Òàáëèöà 5.20
@ Óïðàæíåíèÿ
1. Ïðèâåäèòå ïðèìåð äâóõ ñòðîê. Âû÷èñëèòå äëÿ íèõ ìàò-
ðèöó ðàññòîÿíèé D è ìàòðèöû ðàçíîñòåé D è D¢.
2. Íàïèøèòå ïðîãðàììó äëÿ âîññòàíîâëåíèÿ ìàòðèöû D
ïî çàäàííûì ìàòðèöàì D è D¢.
3. Ïðèâåäèòå ïðèìåðû äâóõ ñòðîê. Âû÷èñëèòå äëÿ íèõ
ìàòðèöû D è D¢ è ïðîâåðüòå ïóòåì ïîäñòàíîâêè çíà÷åíèé
èñòèííîñòü çàâèñèìîñòåé:
1)
Ñìèò Á. Ìåòîäû è àëãîðèòìû âû÷èñëåíèé íà ñòðîêàõ. — Ì.: ÎÎÎ
«È. Ä. Âèëüÿìñ», 2006. Ñ. 332.
2)
Myers G. W. A fast bit–vector algorithm for approximate string matching based
on dynamic programming // JACM 46–3, 1999. P. 395–415.
5.4. Àëãîðèòì Þ. Ìàéåðñà 223
Ìåòîäè÷åñêèé êîììåíòàðèé
Ïðîñòîé àëãîðèòì ðåøåíèÿ ðàññìîòðåííîé â ýòîé ãëàâå çà-
äà÷è îñíîâàí íà èäåÿõ äèíàìè÷åñêîãî ïðîãðàììèðîâàíèÿ, îí
äîñòàòî÷íî õîðîøî èçâåñòåí è ìîæåò áûòü èñïîëüçîâàí êàê çà-
äà÷à ñðåäíåé ñëîæíîñòè ïðè èçó÷åíèè ýòîé òåìû.
Ñ. Âó (Sun Wu) è Þ. Ìàíáåð (Udi Manber)1) â 1992 ã. ðàçðà-
áîòàëè ìåòîä, îáîáùàþùèé àëãîðèòì Shift–And íà íàõîæäå-
íèå íåòî÷íîãî âõîæäåíèÿ îáðàçöà â òåêñòå.
Ðåøåíèå çàäà÷è î k-íåñîâïàäåíèÿõ ïðåäñòàâëåíî ìîäèôè-
êàöèåé àëãîðèòìà Ñ. Âó è Þ. Ìàíáåð, à òàêæå àëãîðèòìîì
Ã. Ëàíäàó è Þ. Âèøêèíà.
Àëãîðèòì Ã. Ëàíäàó (Gad Landau) – Þ. Âèøêèíà (Uzi
Vishkin)2), êðîìå òîãî ÷òî îí îòíîñèòñÿ ê ÷èñëó ïåðâûõ, ïðåä-
íàçíà÷åííûõ äëÿ ðåøåíèÿ çàäà÷è î k-íåñîâïàäåíèÿõ, èìååò
ñâîé, îòëè÷àþùèéñÿ îò ðàíåå ðàññìîòðåííûõ, ìåòîä ïðåäâà-
ðèòåëüíîé îáðàáîòêè îáðàçöà P.
Àëãîðèòì Þ. Ìàéåðñà (Gene Myers)3) (òî÷íåå, åãî ìîäèôè-
êàöèÿ) ñ÷èòàåòñÿ îäíèì èç ñàìûõ ýôôåêòèâíûõ â ðåøåíèè çà-
äà÷è ïîèñêà íåòî÷íîãî âõîæäåíèÿ îáðàçöà â òåêñò. Èäåÿ ìîäè-
1)
Wu S., Manber U. Fast text searching allowing errors // CACM 35–10, 1992.
P. 83–91.
2)
Landau G. M., Vishkin U. Efficient string matching with k mismatches // TCS
43, 1986. P. 239–249.
3)
Myers G. W. A fast bit-vector algorithm for approximate string matching based
on dynamic programming // JACM 46–3, 1999. P. 395–415.
224 Ãëàâà 5. Àëãîðèòìû ïðèáëèæåííîãî ïîèñêà ïîäñòðîê
1)
Ukkonen E. Finding approximate patterns in strings // J. Algs. 6, 1985.
P. 132–137.
2)
Chang W. I., Lawler E. L. Approximate string matching in sublinear expected
time // Proc. 31st Annual IEEE Symp. Foundations of Computer Science. Vol. 1.
1990. P. 116–124.
3)
Cole R., Hariharan R. Faster approximate string matching // Proc. Ninth
Annual ACM-SIAM Symp. Discrete Algs., 1998. P. 463–472.
4)
Baeza-Yates R., Navarro G. Multiple approximate string matching // Proc.
Fifth Annual Workshop on Algorithms & Data Structures. F. Dehne et al. (eds.),
1997. P. 174–184.
Âìåñòî çàêëþ÷åíèÿ
1)
Àâòîð íå èãðàåò çäåñü â èãðó «êòî ïðàâ, êòî âèíîâàò» èëè «÷òî òàêîå õîðîøî,
÷òî òàêîå ïëîõî», à ðàññìàòðèâàåò ñèòóàöèþ êàê äàííîñòü, ñëîæèâøóþñÿ â
õîäå èñòîðè÷åñêîãî ðàçâèòèÿ ÿâëåíèÿ, åñòåñòâåííî, â ðåçóëüòàòå îáúåêòèâ-
íûõ è ñóáúåêòèâíûõ ôàêòîðîâ.
226 Âìåñòî çàêëþ÷åíèÿ
Ðèñ. 1
Ïðèëîæåíèå 1
Íå õâàòàéòå ìåíÿ çà ïàëåö, à ñìîòðèòå,
êóäà ÿ óêàçûâàþ.
Ó. Ìàêêàëîê
Îá îðãàíèçàöèè
ýêñïåðèìåíòàëüíîãî èññëåäîâàíèÿ àëãîðèòìîâ
Ñòîèëî òîëüêî ïîïðîñèòü ìóæ÷èíó ïî-
ìî÷ü âûìûòü ïîñóäó — è òóò æå ïîÿâè-
ëàñü àâòîìàòè÷åñêàÿ ïîñóäîìîéêà.
Ñèðèë Íîðòêîò Ïàðêèíñîí
1. Îáùèå òðåáîâàíèÿ:
l íàëè÷èå äâóõ âåðñèé: ñåòåâîé è ëîêàëüíîé;
l âîçìîæíîñòü óïðàâëåíèÿ äåÿòåëüíîñòüþ øêîëüíèêîâ
(ïîñòàíîâêà çàäà÷, îðãàíèçàöèÿ èíäèâèäóàëüíîé è
ãðóïïîâîé ðàáîòû, âåäåíèå ñòàòèñòè÷åñêèõ äàííûõ î
ðàáîòå øêîëüíèêà è ò. ä.);
1)
Îðãàíèçàöèÿ òàêîé ðàáîòû (ñ ïðèìåðîì óïðàâëÿþùåé ïðîãðàììû) ðàññìîò-
ðåíà â êíèãå: Îêóëîâ Ñ. Ì. Ïðîãðàììèðîâàíèå â àëãîðèòìàõ. — Ì.: ÁÈÍÎÌ.
Ëàáîðàòîðèÿ çíàíèé, 2002. Ñ. 325–328.
236 Ïðèëîæåíèÿ
Ïðèëîæåíèå 2
×åëîâåê íà÷èíàåò æèòü ëèøü òîãäà,
êîãäà åìó óäàåòñÿ ïðåâçîéòè ñàìîãî
ñåáÿ.
Àëüáåðò Ýéíøòåéí
Ïðîáëåìû è çàäà÷è
Ïîðîé çàäà÷à ñòîëü ñëîæíà, ÷òî âîçíè-
êàåò æåëàíèå ïîñìîòðåòü â ãëàçà åå àâ-
òîðó.
Ãåîðãèé Àëåêñàíäðîâ
1)
Îáðàáîòêà çàäà÷íîãî ìàòåðèàëà ïî äàííîé (ðàâíî êàê è ðîäñòâåííîé) ïðîáëå-
ìàòèêå è åãî êëàññèôèêàöèÿ — ýòî ñîäåðæàíèå îòäåëüíîé ðàáîòû, êîòîðîé
åùå íåò â ó÷åáíîé ëèòåðàòóðå ïî èíôîðìàòèêå.
2)
Ãàñôèëä Ä. Ñòðîêè, äåðåâüÿ è ïîñëåäîâàòåëüíîñòè â àëãîðèòìàõ: Èíôîðìà-
òèêà è âû÷èñëèòåëüíàÿ áèîëîãèÿ / Ïåð. ñ àíãë. È. Â. Ðîìàíîâñêîãî. — ÑÏá.:
Íåâñêèé Äèàëåêò; ÁÕ–Ïåòåðáóðã, 2003. Ñ. 56–57.
Ïðèëîæåíèå 2 239
1)
Ãàñôèëä Ä. Ñòðîêè, äåðåâüÿ è ïîñëåäîâàòåëüíîñòè â àëãîðèòìàõ: Èíôîðìà-
òèêà è âû÷èñëèòåëüíàÿ áèîëîãèÿ : Ïåð. ñ àíãë. È. Â. Ðîìàíîâñêîãî. — ÑÏá.:
Íåâñêèé Äèàëåêò; ÁÕÂ-Ïåòåðáóðã, 2003. Ñ. 151–152.
240 Ïðèëîæåíèÿ
f0 = b, f1 = a, fn = fn–1fn–2 (n
2).
Ïåðâûå ñòðîêè Ôèáîíà÷÷è è èõ äëèíû (l):
f0 = b, l = 1;
f1 = a, l = 1;
f2 = ab, l = 2;
f3 = aba, l = 3;
f4 = abaab, l = 5;
f5 = abaababa, l = 8;
f6 = abaababaabaab, l = 13;
f7 = abaababaabaababaababa, l = 21;
f8 = abaababaabaababaababaabaababaabaab, l = 34;
…
Íåòðóäíî çàìåòèòü, ÷òî äëèíû ñòðîê fn óäîâëåòâîðÿþò êëàññè-
÷åñêîìó ñîîòíîøåíèþ: fn = fn–1 + fn–2 (n
2).
Ïðèëîæåíèå 2 243
Òàáëèöà Ï2.1
i 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
S a b c a b d a b c a b d a b c
li 0 0 0 2 1 0 6 6 6 6 5 4 3 2 1
ri 0 0 0 1 2 0 1 2 3 4 5 6 1 2 3
248 Ïðèëîæåíèÿ
1)
Ziv J., Lempel A. A universal algorithm for sequential data compression // IEEE
Trans. on Info. Theory. 1977.Vol. 23. P. 337–343; Ziv J., Lempel A. Compression
of individual sequences via variable length coding // IEEE Trans. on Info.
Theory. 1978. Vol. 24. P. 530–536; Ãàñôèëä Ä. Ñòðîêè, äåðåâüÿ è ïîñëåäîâà-
òåëüíîñòè â àëãîðèòìàõ: Èíôîðìàòèêà è âû÷èñëèòåëüíàÿ áèîëîãèÿ / Ïåð. ñ
àíãë. È. Â. Ðîìàíîâñêîãî. — ÑÏá.: Íåâñêèé Äèàëåêò; ÁÕÂ-Ïåòåðáóðã, 2003.
Ñ. 208–212.
2)
Commentz-Walter B. A string matching algorithm fast on average // Proc. of
the 6th Int. Colloq. on Automata, Languages and Programming. 1979. P.
118–132; Ãàñôèëä Ä. Ñòðîêè, äåðåâüÿ è ïîñëåäîâàòåëüíîñòè â àëãîðèòìàõ:
Èíôîðìàòèêà è âû÷èñëèòåëüíàÿ áèîëîãèÿ / Ïåð. ñ àíãë. È. Â. Ðîìàíîâñêî-
ãî. — ÑÏá.: Íåâñêèé Äèàëåêò; ÁÕÂ-Ïåòåðáóðã, 2003. Ñ. 200–208; Ñìèò Á.
Ìåòîäû è àëãîðèòìû âû÷èñëåíèÿ íà ñòðîêàõ: ïåð. ñ àíãë. — Ì.: ÎÎÎ
«È. Ä. Âèëüÿìñ», 2006. Ñ. 364–366 (ïðàâäà, çäåñü àëãîðèòì íàçûâàåòñÿ «àë-
ãîðèòìîì Êîììåíö-Âàëüòåðà», íî ýòî — ñïåöèôèêà ïåðåâîäà ðàçëè÷íûìè
ëþäüìè).
3)
Îêóëîâ Ñ. Ì. Ðàçâèòèå èíòåëëåêòà øêîëüíèêà. Àáñòðàêòíûå òèïû äàí-
íûõ. — Ì.: ÁÈÍÎÌ. Ëàáîðàòîðèÿ çíàíèé, 2009. Ñ. 96.
Ïðèëîæåíèå 2 249