Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
О.О.П / ооп / 4_кол / К курсовой / Методи побудови алгоритмів та їх аналіз / Інформатика_1 (методи побудови алгоритмівта та їх аналіз).doc
Скачиваний:
87
Добавлен:
30.05.2020
Размер:
2.5 Mб
Скачать

Пошук у рядку

Прямий пошук підрядка у рядку

Нехай треба визначити можливість входження тексту х, що складається з т символів, у текст s, що складається з п сим-волів (т < п). Слід зазначити, що саме така задача є реалізова-ною в будь-якому текстовому редакторі.

Як розв'язувати сформульовану задачу? Першим спадає на думку такий простий алгоритм: будемо послідовно суміщати символи підрядка х із символами рядка s, починаючи з першо-го (мал. 40).

81

S3

...

»*

...

sm

Sm+1

...

Vi

S

л

х1

Х2

хг

...

хн

...

Хп,

Мал. 40

124

При першому ж незбіганні деякого символу підрядка х, тоб-то при виконанні умови хк * sk для k < т (на мал. 40 зображено сірим кольором), зміщуємо накладаиня підрядкя х на рядок s далі вправо на один символ: xL порівнюватимемо з s2, х2 з s3 i т. д. (мал. 41).

«1

«2

«8

...

SmH

...

8п-1

Sn

Х1

Х2

...

**

Хт

Мал. 41

Якщо ж i в цьому разі збігання з відповідним символом ряд­ка s не відбудеться для деякого хк, де k < т, то зміщення підряд-ка х по рядку s продовжимо далі.

Зрозуміло, що цей процес припиниться в одному 3 двох ви-падків:

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

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

Наведений лінійний алгоритм пошуку підрядка у рядку вва-жається найпростішим і є достатньо прозорим.

Запишемо його основну частину у вигляді тексту на мові Pascal:

n := length(s); m := length(x); i:=0;

flag := false; repeat inc(i);

j:=1;

while (x[j] = s[i + j - 1]) and (j <= m) do inc (j);

if j > m then flag := true; until flag or (i > n - m + 1); if flag

then writeln ('Позиція входження ', x,' у', s,':', i)

else writeln ('Текст ', x,' не входить у текст', s,' жодного разу');

Внесемо деякі роз'яснення в текст програми.

Чому в наведеному прикладі використані цикли з післяумо-вою і передумовою, а не цикли з лічильником? Справа в тому, що цикли з лічильником обов'язково виконуються вказану кількість разів. У нашому ж випадку в разі незбігання першо-го ж символу підрядка х з відповідним символом рядка s немає

125

сенсу продовжувати порівняння далі, а можна відразу зміщу-вати підрядок у рядку. Для цього ми використали внутрішній цикл while ... do. Для організації зовнішнього циклу викорис-тано цикл з післяумовою repeat ... until тому, що у випадку повного збігання підрядка у рядку нам потрібно припинити по-шук, але все ж таки хоча б одне накладання підрядка х на ря­док s треба зробити.

Логічна змінна flag відіграє роль індикатора відшукання під-рядка х у рядку s: коли вона набуде значения true, пошук при-пиняється, оскільки це означатиме, що підрядок знайдено.

Зрозуміло, що оцінкою алгоритму лінійного пошуку підряд-ка у рядку є 0{п ■ т), оскільки кожного разу ми повинні всі т символів підрядка х порівнювати із л символами рядка s.

/ Запитання для самоконтролю

  1. Сформулюйте умову класичної задачі пошуку підрядка у рядку. Де ця задача найчастіше використовується?

  2. Зобразіть схематично лінійний алгоритм пошуку підрядка у рядку.

  3. Сформулюйте умови завершения лінійного алгоритму.

  4. Запишіть алгоритм і фрагмент тексту Pascal-програми лінійного пошуку підрядка у рядку.

  5. Обґрунтуйте використання циклів з післяумовою та передумо-вою в реалізації алгоритму лінійного пошуку підрядка у рядку.

  6. Поясніть необхідність використання логічної змінної у лінійному алгоритмі пошуку підрядка у рядку.

  7. Якою є оцінка ефективності роботи алгоритму лінійного пошуку підрядка у рядку?

Завдання

  1. Розробити й реалізувати лінійний алгоритм пошуку під-рядка х у рядку $.

  2. Виконати завдання 1 для підрядка х завдовжки 3 символи у рядку s довжиною в 20 символів, протестувавши його для ви­падку, коли підрядок х входить у рядок s:

  • на початку рядка s;

  • посередині рядка s;

  • у кінці рядка s;

  • декілька разів у рядок s.

3. Виконати завдання 1 для підрядка х довжиною в 10 сим- волів у рядку s довжиною в 255 символів, протестувавши його для випадку, коли підрядок х входить у рядок s:

  • на початку рядка s;

  • посередині рядка s;

  • у кінці рядка s;

  • декілька разів у рядок s.

126

  1. Порівняти результати виконання завдань 2 і 3, визначив-ши загальну кількість порівнянь символів підрядка х із сим­волами рядка s.

  2. Виконати завдання 1 для випадку, коли довжина рядка s перевищує 255 символів.

  3. Виконати завдання 5 для підрядка х довжиною понад 255 символів у рядку s довжиною в 10 000 символів, протестував-ши його для випадку, коли підрядок х входить у рядок s:

  • на початку рядка s;

  • посередині рядка s;

  • у кінці рядка s;

  • декілька разів у рядок s.

7. Порівняти результати виконання завдань 3 і 6, визначив- ши загальну кількість порівнянь символів підрядка х із сим­ волами рядка s.

Соседние файлы в папке Методи побудови алгоритмів та їх аналіз