Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Pract_4.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
55.28 Кб
Скачать

Алгоритм Боуєра та Мура

КМП-пошук дає справжній виграш тільки тоді, коли невдачі передувала деяка кількість збігів. Лише у цьому випадку слово зсовується більше ніж на одиницю. На жаль, це швидше виняток, ніж правило: збіги зустрічаються значно рідше, ніж незбіги. Тому виграш від практичного використання КМП-стратегії в більшості випадків пошуку в звичайних текстах досить незначний. Метод, який запропонували Р. Боуєр і Д. Мур в 1975 р., не тільки покращує обробку самого поганого випадку, але й дає виграш в проміжних ситуаціях.

БМ-пошук базується на незвичних міркуваннях – порівняння символів починається з кінця слова, а не з початку. Як і у випадку КМП-пошуку, слово перед фактичним пошуком трансформується в деяку таблицю. Нехай для кожного символу x із алфавіту величина dx – відстань від самого правого в слові входження x до правого кінця слова. Уявимо, що виявлена розбіжність між словом і текстом. У цьому випадку слово відразу ж можна зсунути праворуч на dpM-1 позицій, тобто на кількість позицій, швидше за все більше одиниці. Якщо символ, який не збігся, тексту в слові взагалі не зустрічається, то зсув стає навіть більшим, а саме зсовувати можна на довжину всього слова. Ось приклад, який ілюструє цей процес:

ABCABCABFABCABD

ABCABD

ABCABD

ABCABD

На початку роботи слід завести масив, який зберігав би для кожного символу, що може зустрітися у масиві a, значення зсуву. Для символів, що взагалі не зустрічаються у образі s, зсув дорівнює M – довжині образу. Для символів, що зустрічаються у s, зсув буде меншим, щоби не пропустити можливих попадань.

Програму можна записати таким чином.

for (ch=0; ch<256; ch++)

d[ch] = M; // замовчування

for (i=0; i<M-1; i++)

d[s[i]] = M-i-1; // уточнення

// Поиск слова p в тексте s

i = M;

do

{

j = M;

k = i;

do // Цикл порівняння символів

{

k--;

j---; // слова, начинаючи з правого

while ( (j<0) || (a[j]!=s[k]) ); //Вихід, при порівн. все слово або незбіг

i += d[s[i-1]]; // Зсув слова вправо

while ( (j<0) || (i>N));

У випадку постійних незбігів цей алгоритм робить одне порівняння на M символів.

Варто сказати, що запропоновані методи пошуку послідовностей можна модифікувати таким чином, щоб у кожному рядку пошук йшов не до кінця кожного рядка, а на кількість шуканих символів менше, бо слово s не може бути розташоване у кінці одного рядка та на початку наступного.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]