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

Поиск подстроки в строке.

Найти подстроку в строке – значит найти первое вхождение, то есть номер символа в строке, с которого начинается подстрока.

XYZACELMABZWV – в строке найти строку AB. Это означает найти номер i символа начала подстроки.

Прямой поиск подстроки.

XYZACELMABZWV

AB

AB

AB

AB …

AB

При прямом поиске подстрока размещается относительно строки таким образом, чтобы первые символы строки и подстроки размещались друг под другом. После этого начинается сравнение. Если символы различны, подстрока сдвигается относительно строки на одну единицу вправо. Если символы одинаковы, сравниваются следующие символы строки и подстроки. Если эти символы различны, подстрока опять сдвигается на одну позицию. И так происходит до тех пор, пока не сравнятся все символы подстроки и строки, либо подстрока не окажется в конце строки (последний символ подстроки будет находиться под последним символом строки).

Фрагмент программы, которая реализует этот алгоритм.

var s, subs: string;

m, n: byte;

i, j: integer;

begin

readln(s); readln(subs);

m := length(subs); n := ord(s[0]);

i := -1;

repeat

i := i + 1; j := 1;

while (j <= m) and (s[i + j] = subs[j]) do j := j + 1;

until (j = m + 1) or (i = n – m);

end.

Во внутреннем цикле осуществляется сравнение подстроки с символами строки, начиная с i-той позиции в строке. Если из цикла вышли, когда j = m + 1, то поиск прошёл успешно, и значение переменной i даёт номер позиции начала подстроки в строке. Если j <> m + 1, a i = n – m, то вхождений не обнаружено.

Алгоритм Боуэра-Мура (БМ-поиск).

В БМ-поиске сравнение символов начинается с конца подстроки. Если символы строки и подстроки одинаковы, то сравниваются следующие символы. Если символы различны, то подстрока сдвигается вправо, причём количество позиций, на которые сдвигается подстрока, зависит от того, есть ли символ строки, с которого началось сравнение, в подстроке, и если есть, на каком расстоянии от конца подстроки он находится. Если символа нет, то сдвиг производится на всю длину подстроки. Если символ есть, величина сдвига равна расстоянию этого символа от конца подстроки.

XYZACELMABZWV

AB

AB

AB

AB

AB

AB

Hoola-Hoola girls like Hooligans

Hooligan

Hooligan

Hooligan

Hooligan

Hooligan

var d: array[char] of byte;

s, p: string;

m, n: byte;

i, j, k: integer;

begin

readln(s); readln(p);

m := length(p); n := length(s);

i := m; j := m;

while (j > 0) and (i <= n) do begin

j := m; k := i;

while (j > 0) and (s[k] = p[j]) do begin

k := k – 1;

j := j – 1;

end;

i := i + d[s[i]];

end;

Если внешний цикл заканчивается при j = 0, то подстрока найдена, и она начинается с позиции k + 1. Если внешний цикл заканчивается при i > n и j > 0, то совпадений не существует. Массив d для каждого символа подстроки, кроме последнего, содержит его расстояние до конца подстроки. Для всех остальных символов в массиве содержится длина подстроки.

for l := 0 to 255 do d[chr(l)] := m;

Этот цикл во все элементы массива d записывает длину подстроки.

for l := 1 to m – 1 do d[p[l]] := m – l;

Анализ алгоритма показывает, что почти всегда требуется значительно меньше, чем n сравнений. В самых же благоприятных случаях, когда последний символ подстроки всегда попадает на несовпадающий символ строки, число сравнений равно n / m.

Задание: написать программу, реализующую два метода поиска подстроки. Каждый из методов поиска реализовать в виде подпрограммы. В качестве параметров подпрограмме передаётся строка и подстрока. Подпрограмма должна вернуть 0 или номер позиции найденной подстроки. Для каждого метода посчитать число сравнений, за которое обнаружили или не обнаружили подстроку.

В основной программе запрашивается ввод имени текстового файла, в котором будет осуществляться поиск. Затем запрашивается ввод подстроки для поиска. После этого организуется цикл (пока не конец файла). Внутри цикла из файла считывается строка, а затем идёт обращение к подпрограммам. Когда файл закончится, выводится сообщение «Строка найдена в … строке файла, начиная с … позиции. Проведено … сравнений».