- •Лабораторная работа №1 «Методы сортировки» Вариант №12 «Пирамидальная сортировка»
- •Лабораторная работа №2 «Методы поиска» Вариант №12 «Метод цепочек»
- •Лабораторная работа №3 «Методы поиска подстроки в строке» Вариант №12 «Кнута-Морриса-Прата»
- •Лабораторная работа №5 «Рекурсия. Фракталы.» Вариант №10 «Салфетка Серпинского»
Лабораторная работа №3 «Методы поиска подстроки в строке» Вариант №12 «Кнута-Морриса-Прата»
Цель работы:
Реализовать заданный метод поиска подстроки в строке в соответствии с индивидуальным заданием. Для всех вариантов добавить реализацию добавления строк, ввода подстроки и поиска подстроки. Предусмотреть возможность существования пробела. Ввести опцию чувствительности / нечувствительности к регистру. Оценить время работы каждого алгоритма поиска и сравнить его со временем работы стандартной функции поиска, используемой в выбранном языке программирования.
Ход работы:
Для реализации целей лабораторной работы выбрала язык программирования Python. Реализуем алгоритм Кнута-Морриса-Прата (КМП)
def compute_prefix_function(pattern): prefix = [0] * len(pattern) j = 0 for i in range(1, len(pattern)): while j > 0 and pattern[i] != pattern[j]: j = prefix[j - 1] if pattern[i] == pattern[j]: j += 1 prefix[i] = j return prefix def kmp_search(text, pattern, case_sensitive=True): if not case_sensitive: text = text.lower() pattern = pattern.lower() prefix = compute_prefix_function(pattern) j = 0 occurrences = [] for i in range(len(text)): while j > 0 and text[i] != pattern[j]: j = prefix[j - 1] if text[i] == pattern[j]: j += 1 if j == len(pattern): occurrences.append(i - j + 1) j = prefix[j - 1] return occurrences
Также реализуем поиск с использованием встроенного поиска Python:
def builtin_search(text, pattern, case_sensitive=True): if not case_sensitive: text = text.lower() pattern = pattern.lower() occurrences = [] start = 0 while True: index = text.find(pattern, start) if index == -1: break occurrences.append(index) start = index + 1 return occurrences
Добавим функцию ввода пользователем строк и подстроки для поиска. Также добавим возможность выйти на любом этапе взаимодействия, чувствительность регистра:
def add_strings(): strings = [] while True: s = input("Введите строку (или 'q' для выхода): ") if s == 'q': break strings.append(s) return strings def get_search_input(): pattern = input("Введите подстроку для поиска: ") case_sensitive = input("Чувствительность к регистру (y/n): ").lower() == 'y' return pattern, case_sensitive
В ходе проведения замеров, произошла ситуация при которой результаты находились слишком быстро, и программа не успевала их подсчитать, поэтому добавим возможность повторения поиска n-количество раз для более точного измерения.
Проведём вычисления:
Строка «Бегемотрвыиаоирвы ыварыоабегемотарои ывоорыВоаиБеГеМоТВТЫВОЛВЫТ овытотвыобегемот»
Подстрока |
КМП, мкс |
Встроенный поиск, мкс |
е |
20.01 |
1.99 |
Бегемот |
19.93 |
2.99 |
мот |
14.06 |
1 |
Код программы:
import time def compute_prefix_function(pattern): prefix = [0] * len(pattern) j = 0 for i in range(1, len(pattern)): while j > 0 and pattern[i] != pattern[j]: j = prefix[j - 1] if pattern[i] == pattern[j]: j += 1 prefix[i] = j return prefix def kmp_search(text, pattern, case_sensitive=True): if not case_sensitive: text = text.lower() pattern = pattern.lower() prefix = compute_prefix_function(pattern) j = 0 occurrences = [] for i in range(len(text)): while j > 0 and text[i] != pattern[j]: j = prefix[j - 1] if text[i] == pattern[j]: j += 1 if j == len(pattern): occurrences.append(i - j + 1) j = prefix[j - 1] return occurrences def builtin_search(text, pattern, case_sensitive=True): if not case_sensitive: text = text.lower() pattern = pattern.lower() occurrences = [] start = 0 while True: index = text.find(pattern, start) if index == -1: break occurrences.append(index) start = index + 1 return occurrences def add_strings(): strings = [] while True: s = input("Введите строку (или 'q' для выхода): ") if s == 'q': break strings.append(s) return strings def get_search_input(): pattern = input("Введите подстроку для поиска: ") case_sensitive = input("Чувствительность к регистру (y/n): ").lower() == 'y' return pattern, case_sensitive def measure_time(func, *args, repetitions=1000): total_time = 0 for _ in range(repetitions): start_time = time.time() result = func(*args) end_time = time.time() total_time += (end_time - start_time) * 1_000_000 return total_time / repetitions, result def main(): strings = add_strings() if not strings: print("Строки не добавлены.") return while True: pattern, case_sensitive = get_search_input() for text in strings: print(f"\nПоиск в строке: '{text}'") kmp_time, kmp_result = measure_time(kmp_search, text, pattern, case_sensitive) print(f"КМП: найдено вхождений — {len(kmp_result)}, время — {kmp_time:.2f} мкс") builtin_time, builtin_result = measure_time(builtin_search, text, pattern, case_sensitive) print(f"Встроенный поиск: найдено вхождений — {len(builtin_result)}, время — {builtin_time:.2f} мкс") if kmp_result == builtin_result: print("Результаты совпадают.") else: print("Результаты не совпадают!") choice = input("\nХотите продолжить поиск? (y/n): ").lower() if choice != 'y': print("Поиск завершен.") break if __name__ == "__main__": main()
Вывод:
В связи с проведенными вычислениями, можно сделать вывод что Встроенный поиск Python работает быстрее чем метод поиска подстроки Кнута-Морриса-Прата
Лабораторная работа №4 «Реализация стека/дека»
Вариант №10 «Дан файл из символов. Используя стек, за один просмотр файла напечатать сначала все цифры, затем все буквы, и, наконец, все остальные символы, сохраняя исходный порядок в каждой группе символов.»
Цель работы:
Разработать программу на Python, которая с использованием стека обрабатывает файл символов, разделяя их на три группы (цифры, буквы, остальные символы) и выводя их в исходном порядке внутри каждой группы.
Вводимые данные для тестирования в файле input.txt:
hbvsdjchblcdshfcis7yf8w7ryr23b9urq30rb329rbud-bG87G80gb*VB*yv)&vd)&v&(3RU4B IEWNFHJCBSD
Код программы:
class Stack: def __init__(self): self.items = [] def is_empty(self): return len(self.items) == 0 def push(self, item): self.items.append(item) def pop(self): if not self.is_empty(): return self.items.pop() return None def size(self): return len(self.items) def process_file(filename): digits = [] letters = [] others = [] with open(filename, 'r', encoding='utf-8') as file: for line in file: for char in line: if char.isdigit(): digits.append(char) elif char.isalpha(): letters.append(char) else: others.append(char) print("Цифры:", ''.join(digits)) print("Буквы:", ''.join(letters)) print("Остальные символы:", ''.join(others)) if __name__ == "__main__": filename = "input.txt" process_file(filename)
Результат выполнения:
Цифры: 78723930329878034
Буквы: hbvsdjchblcdshfcisyfwryrburqrbrbudbGGgbVByvvdvRUBIEWNFHJCBSD
Остальные символы: -**)&)&&(
