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

Результаты работы

В ходе выполнения поставленной задачи были получены следующие результаты:

Размер массива

Время

Рис. 5. Сравнение временных затрат на поиск алгоритмами КМП и Прямой

На рис. 5 синим цветом отмечен алгоритм Прямой, оранжевым – КМП. Согласно информации с графика, Прямой алгоритм медленнее алгоритма КМП. Также стоит отметить, что прямой алгоритм сильнее замедляется с увеличением размерности строки. В связи с этим можно сказать, что прямой алгоритм в среднестатистической ситуации, когда искомая подстрока может находиться, как в начале, так и в любой другой части строки, предпочтительнее КМП благодаря своей более низкой сложности.

Вывод

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

Приложение

#include <iostream>

#include <string>

#include <ctime>

#include <chrono>

#include <random>

#include <locale.h>

using namespace std;

// Функция для генерации случайного символа

char getRandomChar() {

const char str[] = { 'A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g', 'H', 'h', 'I', 'i', 'J', 'j', 'K', 'k', 'L', 'l', 'M', 'm', 'N', 'n', 'O', 'o', 'P', 'p', 'Q', 'q', 'R', 'r', 'S', 's', 'T', 't', 'U', 'u', 'V', 'v', 'W', 'w', 'X', 'x', 'Y', 'y', 'Z', 'z' };

return str[rand() % 52];

}

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

int find_substrings(string S, string W) {

unsigned int i, j;

int number = 0;

for (i = 0; i < S.length() - W.length() + 1; i++) {

j = 0;

while ((j < W.length()) && (W[j] == S[i + j])) {

j = j + 1;

}

if (j == W.length()) {

number++;

}

}

return number;

}

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

int KMPSearch(string text, string pattern) {

int n = text.length();

int m = pattern.length();

int count = 0;

// Создаем префикс-функцию

vector<int> pi(m);

pi[0] = 0;

int k = 0;

for (int i = 1; i < m; i++) {

while (k > 0 && pattern[k] != pattern[i])

k = pi[k - 1];

if (pattern[k] == pattern[i])

k++;

pi[i] = k;

}

// Поиск подстроки

k = 0;

for (int i = 0; i < n; i++) {

while (k > 0 && pattern[k] != text[i])

k = pi[k - 1];

if (pattern[k] == text[i])

k++;

if (k == m) {

count++;

k = pi[k - 1];

}

}

return count;

}

int main() {

setlocale(LC_ALL, "Russian");

srand(time(0));

int n;

cout << "Введите длину текста: ";

cin >> n;

// Генерация случайной подстроки длиной 4

string pattern = "";

for (int i = 0; i < 4; i++) {

pattern += getRandomChar();

}

// Создание текста с вставленной подстрокой каждые 30 символов

string text = "";

for (int i = 0; i < n; i++) {

if (i % 30 == 0 && i + 4 <= n) {

text += pattern;

i += 3; // Пропускаем 3 позиции, т.к. четвертая будет пропущена в цикле

}

else {

text += getRandomChar();

}

}

// Замер времени для прямого поиска

auto start = chrono::high_resolution_clock::now();

int count1 = find_substrings(text, pattern);

auto end = chrono::high_resolution_clock::now();

chrono::duration<double, milli> bruteforce_time = end - start;

// Замер времени для алгоритма КМП

start = chrono::high_resolution_clock::now();

int count2 = KMPSearch(text, pattern);

end = chrono::high_resolution_clock::now();

chrono::duration<double, milli> kmp_time = end - start;

cout << "Искомая подстрока: " << pattern << endl;

cout << "\nРезультаты поиска:" << endl;

cout << "Прямой поиск нашел " << count1 << " вхождений за "

<< bruteforce_time.count() << " мс" << endl;

cout << "Алгоритм КМП нашел " << count2 << " вхождений за "

<< kmp_time.count() << " мс" << endl;

return 0;

}

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

2025