Добавил:
baraevaliza
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабы по АиСД 2023 / Baraeva_Elizaveta_lb4
.pdf
МИНОБРНАУКИ РОССИИ
САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ
ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
«ЛЭТИ» ИМ. В. И. УЛЬЯНОВА (ЛЕНИНА)
Кафедра МО ЭВМ
ОТЧЕТ
по лабораторной работе №4
по дисциплине «Алгоритмы и структуры данных»
Тема: Поиск образца в тексте. Алгоритм Рабина-Карпа
Студентка гр. 2383
Бараева Е. Н.
Преподаватель
Гаврилов А. В.
Санкт-Петербург
2023

2
Цель работы.
Реализация и исследование алгоритма Карпа-Рабина для поиска образца
в тексте, а также сравнение полученных результатов с теоретической оценкой.
Задание.
Напишите программу, которая ищет все вхождения строки Pattern в
строку Text, используя алгоритм Карпа-Рабина.
На вход программе подается подстрока Pattern и текст Text. Необходимо
вывести индексы вхождений строки Pattern в строку Text в возрастающем
порядке, используя индексацию с нуля.
Примечание: в работе запрещено использовать библиотечные
реализации алгоритмов и структур.
Ограничения
1 ≤ |Pattern| ≤ |Text| ≤ 5 · 105.
Суммарная длина всех вхождений образца в текста не превосходит 108.
Обе строки содержат только буквы латинского алфавита.
Подсказки:
1. Будьте осторожны с операцией взятия подстроки — она может
оказаться дорогой по времени и по памяти.
2. Храните степени x ** p в списке - тогда вам не придется вычислять их
каждый раз заново.
Выполнение работы.
В начале определены две переменные d и mod, которые используются
для вычисления хеша. Далее функция RabinKarp, которая принимает две
строки pattern и text, возвращает список индексов, где найдено совпадение.
Внутри функции происходит вычисление длины строк pattern и text и
проверка на их соответствие. Если длина text меньше длины pattern или
длина pattern равна нулю, то функция возвращает пустой список. Далее
инициализируются переменные pattern_hash, text_hash, answer и h. Затем в

3
цикле вычисляются хеши для pattern и text. После во внешнем цикле
происходит сравнение хешей pattern и текущего подстроки text. Если они
совпадают, то во внутреннем цикле происходит сравнение символов pattern и
текущей подстроки text. Если они совпадают, то индекс текущей подстроки
добавляется в список answer. После этого происходит обновление хеша text
при переходе к следующей подстроке. Если значения text_hash становится
отрицательным, то оно суммируется с mod. В конеце функция возвращает
список answer. После функции происходит ввод пользователем в строки
pattern и text, а затем вызывается функция RabinKarp с этими аргументами и
результат выводится на экран.
Разработанный программный код см. в приложении А.
Тестирование.
Результаты тестирования представлены в табл. 1.
Таблица 1 – Результаты тестирования
№
п/п
Входные данные
Выходные данные
Комментарии
1.
"text"
"texttttttext"
[0, 8]
Верно.
2.
"text"
"tetextttr5656ttttextex334t
eeeet2ttxtextxxtexttext"
[2, 16, 35, 41, 45]
Верно.
3.
""
""
[]
Верно.
Вывод.
Был создан алгоритм Рабина-Карпа для поиска подстроки в тексте. Он
использует хеширование, что является его главным отличием. Ключевыми
факторами успеха этого алгоритма являются низкая вероятность коллизий и
возможность эффективно вычислять хеш-значение последовательных
подстрок. Результаты тестирования алгоритма показали его эффективность
поиска на текстах со значительным объемом слов.

4
ПРИЛОЖЕНИЕ А
ИСХОДНЫЙ КОД ПРОГРАММЫ
Название файла: main.py
d = 2 ** 11 - 1
mod = 2 ** 31 - 1
def RabinKarp(pattern: str, text: str) -> list:
length_text, length_pattern = len(text), len(pattern)
if length_text < length_pattern or length_pattern == 0:
return []
pattern_hash = 0
text_hash = 0
answer = []
h = pow(d, length_pattern - 1, mod)
for i in range(length_pattern):
pattern_hash = (d * pattern_hash + ord(pattern[i])) % mod
text_hash = (d * text_hash + ord(text[i])) % mod
for i in range(length_text - length_pattern + 1):
if pattern_hash == text_hash:
for j in range(length_pattern):
if text[i + j] != pattern[j]:
break
else:
answer.append(i)
if i < length_text - length_pattern:
text_hash = (d * (text_hash - ord(text[i]) * h) +
ord(text[i + length_pattern])) % mod
if text_hash < 0:
text_hash = text_hash + mod
return answer
pattern = input()
text = input()
print(*RabinKarp(pattern, text))
Название файла: test.py
import main
def test_middle():
text = "texttttttext"
pattern = "text"
assert (main.RabinKarp(pattern, text) == [0, 8])
def test_big():

5
text = "tetextttr5656ttttextex334teeeet2ttxtextxxtexttext"
pattern = "text"
assert (main.RabinKarp(pattern, text) == [2, 16, 35, 41, 45])
def test_small():
text = "1t"
pattern = "t"
assert (main.RabinKarp(pattern, text) == [1])
def test_none():
text = ""
pattern = ""
assert (main.RabinKarp(pattern, text) == [])
Соседние файлы в папке Лабы по АиСД 2023
