Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы по АиСД 2023 / Baraeva_Elizaveta_lb4

.doc
Скачиваний:
0
Добавлен:
09.09.2026
Размер:
63 Кб
Скачать

МИНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В. И. Ульянова (Ленина)

Кафедра МО ЭВМ

отчет

по лабораторной работе №4

по дисциплине «Алгоритмы и структуры данных»

Тема: Поиск образца в тексте. Алгоритм Рабина-Карпа

Студентка гр. 2383

Бараева Е. Н.

Преподаватель

Гаврилов А. В.

Санкт-Петербург

2023

Цель работы.

Реализация и исследование алгоритма Карпа-Рабина для поиска образца в тексте, а также сравнение полученных результатов с теоретической оценкой.

Задание.

Напишите программу, которая ищет все вхождения строки 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. Затем в цикле вычисляются хеши для pattern и text. После во внешнем цикле происходит сравнение хешей pattern и текущего подстроки text. Если они совпадают, то во внутреннем цикле происходит сравнение символов pattern и текущей подстроки text. Если они совпадают, то индекс текущей подстроки добавляется в список answer. После этого происходит обновление хеша text при переходе к следующей подстроке. Если значения text_hash становится отрицательным, то оно суммируется с mod. В конеце функция возвращает список answer. После функции происходит ввод пользователем в строки pattern и text, а затем вызывается функция RabinKarp с этими аргументами и результат выводится на экран.

Разработанный программный код см. в приложении А.

Тестирование.

Результаты тестирования представлены в табл. 1.

Таблица 1 – Результаты тестирования

№ п/п

Входные данные

Выходные данные

Комментарии

1.

"text"

"texttttttext"

[0, 8]

Верно.

2.

"text"

"tetextttr5656ttttextex334teeeet2ttxtextxxtexttext"

[2, 16, 35, 41, 45]

Верно.

3.

""

""

[]

Верно.

Вывод.

Был создан алгоритм Рабина-Карпа для поиска подстроки в тексте. Он использует хеширование, что является его главным отличием. Ключевыми факторами успеха этого алгоритма являются низкая вероятность коллизий и возможность эффективно вычислять хеш-значение последовательных подстрок. Результаты тестирования алгоритма показали его эффективность поиска на текстах со значительным объемом слов.

ПРИЛОЖЕНИЕ А ИСХОДНЫЙ КОД ПРОГРАММЫ

Название файла: 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():

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) == [])

5

Соседние файлы в папке Лабы по АиСД 2023