Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритмы и структуры данных.doc
Скачиваний:
81
Добавлен:
01.05.2014
Размер:
411.14 Кб
Скачать

3.4. Поиск фрагмента в тексте Постановка задачи

Для слов Y = YY2 … Yn и X = XX2 … Xm в алфавите A найти все вхождения слова Y в X. В дальнейшем под решением этой задачи мы будем понимать такую функцию f: {1, 2, … ,m}{0, 1, 2, … , n}, что f[j] = n, если YY2 … Yn =X j-(n-1) X j-(n-2) … X j (на j-ой букве слова X заканчивается очередное вхождение в него слова Y), и f[j]<n в противном случае. Для избавления псевдокодов алгоритмов от мешающих их пониманию деталей, мы будем в дальнейшем считать, что 1≤n≤m.

Наивный алгоритм поиска фрагмента в тексте

Суть данного алгоритма иллюстрируется рамкой длины n, движущейся по слову X. Если фрагмент слова X, находящийся в рамке, совпадает со словом Y, это означает, что очередное вхождение слова Y в X найдено.

procedure SFT_TRIVIAL(X; m; Y; n; var f);

begin

for i:= 1 to n-1 do f[i]:= 0;

for i:= n to m do begin

s:= 1;

while (Y[s] =X[i-(n-s)]) (s<n) do s:= s+1;

if (s=n) (Y[n] =X[i]) then f[i]:= n else f[i]:= 0;

end;

end;

Временная сложность наивного алгоритма есть O(nm).

Алгоритм Кнута-Морриса-Пратта

В общем виде алгоритм Кнута-Морриса-Пратта (см. [4], [5]) строит функцию откатов fY: {1, 2, … ,n}{0, 1, 2, … , n-1} для поданного на его вход слова Y = YY2 … Yn. Таким образом, fY[i] является длиной наибольшего собственного суффикса слова Y = YY2 … Yn, который является также и его префиксом.

procedure KMP(Y; n; var fY);

begin

i:= 1; fY[1]:= 0;

while i<n do begin

j:= fY[i];

while (Y[j+1]  Y[i+1]) (j>0) do j:= fY[j];

if Y[j+1] = Y[i+1] then f[i+1]:= j+1 else f[i+1]:= 0;

i:= i+1;

end;

end;

Тогда исходную задачу поиска всех вхождений слова Y = YY2 … Yn в слово (текст) X = XX2 … Xm решит построение функции откатов fZ для слова Z=Y#X, где # является произвольной буквой, не принадлежащей алфавиту A. В этом случае искомую функцию f можно найти, положив f[i]=fZ[i+n+1], i = 1, …, m. Сохраняя неизменной суть данного построения функции f, удается организовать его так, чтобы не было необходимости вводить в алфавит новую букву. Таким образом, алгоритм Кнута-Морриса-Пратта поиска всех вхождений слова Y=YY2 … Yn в X=XX2 … Xm можно представить в следующем виде.

procedure SFT_KMP(X; m; Y; n; var f);

begin

KMP(Y, n, fY);

i:= 1; if Y[1]=X[1] then f[1]:= 1 else f[1]:= 0;

while i<m do begin

j:= f[i];

if j=n then j:= fY[j];

while (Y[j+1]  X[i+1])  (j>0) do j:= fY[j];

if Y[j+1] = X[i+1] then f[i+1]:= j+1 else f[i+1]:= 0;

i:= i+1;

end;

end;

Временная сложность алгоритма Кнута-Морриса-Пратта есть O(n+m).

Задания для лабораторной работы № 4

  1. Написать программу, реализующую тривиальный алгоритм и алгоритм Кнута-Морриса-Пратта поиска фрагмента в тексте, основываясь соответственно на псевдокодах процедур SFT_TRIVIAL и SFT_KMP.

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

  • количество букв в алфавите,

  • способ независимого друг от друга задания слов X и Y из числа следующих:

  • непосредственный ввод слова,

  • образование слова выбранной длины, составленного из выбранных букв алфавита, встречающихся равновероятно,

  • образование слова вида (BB Bs)k на основе ввода числа k и слова B1B Bs.

  1. Выходом данной программы должно быть время работы T1 тривиального алгоритма и время работы T2 алгоритма Кнута-Морриса-Пратта в секундах.

  2. Провести эксперименты на основе следующих данных:

    1.  Y=(ab)k и X=(ab)1000*k, k = 1, … ,1001 с шагом 10 (нарисовать графики функций T1(k) и T2(k));

    2.  A={a,b}, Y=(a)m, слово X состоит из 106+1 букв алфавита A, встречающихся равновероятно, m = 1, … ,106+1 с шагом 104 (нарисовать графики функций T1(m) и T2(m));

    3.  Y=aaaaa и X=(aaaaab)h, h = 1, … ,106+1 с шагом 104 (нарисовать графики функций T1(h) и T2(h)).

  3. Сформулировать и обосновать (на основе псевдокодов алгоритмов и практических данных, для получения которых можно провести дополнительные эксперименты) вывод о том, в каких случаях целесообразно применять тривиальный алгоритм, а в каких ― алгоритм Кнута-Морриса-Пратта.