- •Інформатика
- •Необчислювальні алгоритмы
- •Від автора
- •Створення алгоритму
- •Налагодження алгоритму
- •Допоміжні задачі
- •Поняття систем числення
- •Числова інформація Цілі числа
- •Дійсні числа
- •Текстова інформація Символи
- •Дерево. Бінарне дерево
- •If to nil then with t* do begin
- •Бінарний пошук Пошук діленням навпіл
- •Рекурсивний бінарний пошук
- •Пошук у рядку
- •Скінченні автомати Основні поняття
- •Пошук у мережі
- •Прямі методи сортування Сортування вибором
- •Сортування обміном
- •Шейкерне сортування
- •Сортування методом Шелла
- •Швидке сортування
- •Метод прямого злиття
- •Метод природного злиття
- •Сортування підрахунком
- •Цифрове сортування
- •Література
- •61012, М. Харків, вул. Енгельса, 11.
Пошук у рядку
Прямий пошук підрядка у рядку
Нехай треба визначити можливість входження тексту х, що складається з т символів, у текст 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.
/ Запитання для самоконтролю
-
Сформулюйте умову класичної задачі пошуку підрядка у рядку. Де ця задача найчастіше використовується?
-
Зобразіть схематично лінійний алгоритм пошуку підрядка у рядку.
-
Сформулюйте умови завершения лінійного алгоритму.
-
Запишіть алгоритм і фрагмент тексту Pascal-програми лінійного пошуку підрядка у рядку.
-
Обґрунтуйте використання циклів з післяумовою та передумо-вою в реалізації алгоритму лінійного пошуку підрядка у рядку.
-
Поясніть необхідність використання логічної змінної у лінійному алгоритмі пошуку підрядка у рядку.
-
Якою є оцінка ефективності роботи алгоритму лінійного пошуку підрядка у рядку?
Завдання
-
Розробити й реалізувати лінійний алгоритм пошуку під-рядка х у рядку $.
-
Виконати завдання 1 для підрядка х завдовжки 3 символи у рядку s довжиною в 20 символів, протестувавши його для випадку, коли підрядок х входить у рядок s:
-
на початку рядка s;
-
посередині рядка s;
-
у кінці рядка s;
-
декілька разів у рядок s.
3. Виконати завдання 1 для підрядка х довжиною в 10 сим- волів у рядку s довжиною в 255 символів, протестувавши його для випадку, коли підрядок х входить у рядок s:
-
на початку рядка s;
-
посередині рядка s;
-
у кінці рядка s;
-
декілька разів у рядок s.
126
-
Порівняти результати виконання завдань 2 і 3, визначив-ши загальну кількість порівнянь символів підрядка х із символами рядка s.
-
Виконати завдання 1 для випадку, коли довжина рядка s перевищує 255 символів.
-
Виконати завдання 5 для підрядка х довжиною понад 255 символів у рядку s довжиною в 10 000 символів, протестував-ши його для випадку, коли підрядок х входить у рядок s:
-
на початку рядка s;
-
посередині рядка s;
-
у кінці рядка s;
-
декілька разів у рядок s.
7. Порівняти результати виконання завдань 3 і 6, визначив- ши загальну кількість порівнянь символів підрядка х із сим волами рядка s.