Скачиваний:
0
Добавлен:
02.11.2025
Размер:
88.69 Кб
Скачать

Описание программы

Работа была выполнена на языке программирования C++ с использованием среды разработки Visual Studio Community 2022 версии 17.7.4.

Использованные библиотеки: iostream, cstdlib, ctime, chrono, locale

Сама программа включает в себя несколько функций, как:

  1. int find_substrings(string S, string W)

  2. int KMPSearch(char *string, char *substring)

  3. char getRandomChar()

Функция 1 является алгоритмом прямого поиска. Прямой поиск осуществляется путем сравнения каждого символа подстроки с символами строки. Если символы не совпадают, то происходит сдвиг и поиск продолжается со следующего символа в строке. Этот алгоритм позволяет найти первое вхождение подстроки в строке и может быть эффективен для не слишком длинных строк и коротких подстрок. В качестве результата возвращает индекс первого элемента, с которого пошло совпадение. В обратном случае возвращается «-1», что сигнализирует об отсутствии результата.

Функция 2 является алгоритмом Кнута-Морриса-Пратта и работает по такому же принципу, что и функция 1 – получает ссылки на массив основной строки и подстроки, возвращает результат.

Функция 3 является служебной функцией, используемой для заполнения массивов строки и подстроки. При помощи метода rand библиотеки stdlib.h возвращает случайный символ из 52 символов – строчных и заглавных латинских букв.

В int main() происходят основные операции, необходимые для выполнения поставленной задачи: здесь инициализируется количество повторов (int times) и количество шагов. Далее инициализируются динамические массивы для хранения результатов подсчета времени для КМП и Прямого соответственно chrono::duration<double, milli> bruteforce_time = end - start; и chrono::duration<double, milli> kmp_time = end – start.

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

Сравнение и тестирование

Пример реализации методов поиска подстроки (таблица 3).

Подстрока: АВСАВD

 

Текст для поиска:

ABCABCAABCABD

 

Алгоритм Кнута-Морриса-Пратта

Префикс-функция:

"000120"

 

Процесс поиска:

Шаг 1

ABCABCAABCABD

 

Шаг 2

ABCABCAABCABD

 

Шаг 3

ABCABCAABCABD

 

 

Шаг 4

ABCABCAABCABD

Алгоритм прямого поиска

Процесс поиска:

Шаг 1

ABCABCAABCABD

 

Шаг 2

АВСАВD

 

Шаг 3

АВСАВD

 

Шаг 4

АВСАВD

 

Шаг 5

АВСАВD

 

Шаг 6

АВСАВD

 

Шаг 7

АВСАВD

 

Шаг 8

АВСАВD

 

Шаг 9

АВСАВD

 

Шаг 10

АВСАВD

 

Шаг 11

АВСАВD

 

Шаг 12

АВСАВD

 

Шаг 13

АВСАВD

 

Шаг 14

АВСАВD

 

Шаг 15

АВСАВD

 

Шаг 16

АВСАВD

 

Шаг 17

АВСАВD

 

Шаг 18

АВСАВD

 

Шаг 19

АВСАВD

 

Шаг 20

АВСАВD

 

 

Шаг 21

АВСАВD

Таблица 3. Сравнение алгоритмов

Алгоритм прямого поиска

На первом шаге происходит сравнение первых шести символов строки и подстроки: это ABCABD и ABCABC. Совпадает первый символ.

Со второго шага начинается посимвольное сравнение строки и подстроки. Если найдено совпадение, то позиция не сдвигается, а сравнивается следующий символ подстроки со строкой, и так до тех пор, пока не будет обнаружено полное совпадение или его отсутствие. В нашем случае на втором шаге фиксируется совпадение первого символа подстроки «А», на третьем шаге — второго символа «B», на четвёртом шаге — символа «С», на пятом шаге — символа «А», на шестом шаге — символа «В».

На седьмом шаге происходит сдвиг на одну позицию, так как шестой символ строки не совпал с последним символом подстроки. На этом шаге сравнивается ABCABD и BCABCA. Совпадения нет.

На восьмом шаге происходит сдвиг на одну позицию, так как в текущей позиции совпадений нет. На этом шаге сравнивается ABCABD и CABCAA.

На девятом шаге происходит сравнение четвёртого символа строки и первого символа подстроки. Найдено совпадение символа «А». В нашем случае на десятом шаге фиксируется совпадение второго символа «B», на одиннадцатом шаге — символа «С», на двенадцатом шаге — символа «А». Совпадение закончилось, происходит сдвиг.

На тринадцатом шаге происходит сдвиг, так как совпадений нет. На этом шаге происходит сравнение ABCABD и BCAABC.

На четырнадцатом шаге сравнивается ABCABD и CAABCA. Совпадение не найдено, происходит сдвиг.

На пятнадцатом шаге сравнивается ABCABD и AABCAB. Совпадение не найдено, происходит сдвиг.

На шестнадцатом шаге сравнивается ABCABD и ABCABD. Фиксируется совпадение первого символа. На семнадцатом шаге фиксируется совпадение второго символа «B», на восемнадцатом шаге — символа «С», на девятнадцатом шаге — символа «А», на двадцатом — символа «B», на двадцать первом шаге — символа «D». Найдено полное совпадение.

Алгоритм Кнута-Морриса-Пратта

Предобработка. Составление префикс-функции.

Для 1 элемента подстроки сравним префикс (желтый) и суффикс (зеленый). ABCABD – совпадения нет, значение равно 0.

Для 2 элемента подстроки: ABCABD. Не забываем, что префикс и суффикс могут пересекаться, однако, АB не равняется BC. Совпадения нет, значение = 0.

Для 3 элемента подстроки: ABCABD. Совпадение есть, сравнение дальше: ABCABD. Совпадения нет, при дальнейшем сравнении тоже, значение = 1.

Для 4 элемента подстроки: ABCABD. Не совпадает, сравнение дальше: ABCABD. Совпадают 2 элемента, при дальнейшем сравнении перемен не будет, значение = 2.

Для 5 элемента подстроки: ABCABD. Совпадения нет, при дальнейшем сравнении тоже, значение = 0.

В итоге, для ABCABD массив значений префикс-функции выглядит следующим образом: 000120.

После этого осуществляется сам поиск подстроки в строке ABCABCAABCABD. На первом шаге сравнивается ABCABD и ABCABC. Не совпадает элемент 5. Значение префикс-функции для предыдущего элемента = 2. Переносим всю подстроку вправо так, что она будет начинаться на 2 элемента левее места несовпадения, т.е., сдвигая на 2 элемента влево.

На втором шаге поиска сравнивается ABCABD и ABCAAB. Не совпадает элемент 4. Значение префикс-функции для предыдущего элемента = 1. Переносим всю строку вправо так, что она будет начинаться на 1 элемент левее места несовпадения, т.е., сдвигая на 1 элемент влево.

На третьем шаге сравнивается ABCABD и AABCAB. Несовпадение на элементе 1. Значение префикс-функции для предыдущего элемента = 0. Переносим всю строку вправо так, что она будет начинаться на месте несовпадения, т.е., без сдвига.

На четвертом шаге сравнивается ABCABD и ABCABD. Совпадение, подстрока найдена.