Тестирование.
Результаты тестирования представлены в табл. 1.
Таблица 1 – Результаты тестирования
№ п/п |
Входные данные |
Выходные данные |
Комментарии |
1. |
NTAG 3 TAGT TAG T |
2 2 2 3 |
Задание 1. Верно. |
2. |
ACTANCA A$$A$ $ |
1 |
Задание 2. Верно. |
3. |
ACGTNNNACGTTAGNC 3 GNCA NNN ACGTNNNACGTTAGNC |
1 3 5 2 |
Задание 1. Верно. |
4. |
ACGAGAGAGANTTTANA G&& & |
3 5 7 9 |
Задание 2. Верно. |
Вывод.
Был изучен и реализован алгоритм Ахо-Корасик для поиска набора образцов в тексте, а также для одного образца с джокером. Была изучена такая ключевая структура данных, как бор, а также изучено построение конечного автомата. Использование данных техник позволило достичь линейной скорости поиска множества образцов в тексте за счёт предварительной обработки. Алгоритм Ахо-Корасик наиболее эффективен в ситуациях, когда требуется выполнить множество поисковых запросов по одному и тому же набору паттернов в различных текстах. Это особенно полезно, когда набор паттернов не изменяется, а количество текстов для поиска велико. Использование алгоритма Ахо-Корасик позволяет избежать повторной предварительной обработки паттернов для каждого отдельного текста, что значительно ускоряет процесс поиска.
Приложение а исходный код программы
Название файла: aho.py
from collections import deque
class Node:
def __init__(self, suffix_link=None):
self.words = []
self.child = {}
self.suffix_link = suffix_link
class Trie:
def __init__(self, patterns):
self.root = Node()
self.node = self.root
self.create_tree(patterns)
self.create_links()
def create_tree(self, patterns):
for index, pattern in enumerate(patterns):
node = self.root
for symbol in pattern:
if symbol not in node.child:
node.child[symbol] = Node(self.root)
node = node.child[symbol]
node.words.append(index)
def create_links(self):
queue = deque()
for _, node in self.root.child.items():
queue.append(node)
while queue:
current_node = queue.popleft()
for symbol, node in current_node.child.items():
link_node = current_node.suffix_link
while link_node is not None and symbol not in link_node.child:
link_node = link_node.suffix_link
if link_node is not None:
node.suffix_link = link_node.child[symbol]
else:
node.suffix_link = self.root
node.words.extend(node.suffix_link.words)
queue.append(node)
def find_start(self, symbol):
while self.node is not None and symbol not in self.node.child:
self.node = self.node.suffix_link
if self.node is None:
self.node = self.root
return None
self.node = self.node.child[symbol]
return self.node
def run_aho_corasick(text, patterns):
trie = Trie(patterns)
answer = []
for index, symbol in enumerate(text):
node = trie.find_start(symbol)
if node:
for pattern_index in node.words:
answer.append((index + 2 - len(patterns[pattern_index]), pattern_index + 1))
return answer
if __name__ == "__main__":
text = input()
n = int(input())
patterns = [input() for _ in range(n)]
answer = run_aho_corasick(text, patterns)
answer.sort()
for index, pattern_index in answer:
print(index, pattern_index)
Название файла: aho_wild_card.py
from collections import deque
class Node:
def __init__(self, suffix_link=None):
self.words = []
self.child = {}
self.suffix_link = suffix_link
class Trie:
def __init__(self, patterns):
self.root = Node()
self.node = self.root
self.create_tree(patterns)
self.create_links()
def create_tree(self, patterns):
for index, pattern in enumerate(patterns):
node = self.root
for symbol in pattern:
if symbol not in node.child:
node.child[symbol] = Node(self.root)
node = node.child[symbol]
node.words.append(index)
def create_links(self):
queue = deque()
for _, node in self.root.child.items():
queue.append(node)
while queue:
current_node = queue.popleft()
for symbol, node in current_node.child.items():
link_node = current_node.suffix_link
while link_node is not None and symbol not in link_node.child:
link_node = link_node.suffix_link
if link_node is not None:
node.suffix_link = link_node.child[symbol]
else:
node.suffix_link = self.root
node.words.extend(node.suffix_link.words)
queue.append(node)
def find_start(self, symbol):
while self.node is not None and symbol not in self.node.child:
self.node = self.node.suffix_link
if self.node is None:
self.node = self.root
return None
self.node = self.node.child[symbol]
return self.node
def run_aho_corasick(text, patterns):
trie = Trie(patterns)
answer = []
for index in range(len(text)):
node = trie.find_start(text[index])
if node:
for pattern_index in node.words:
answer.append((index + 1 - len(patterns[pattern_index]), pattern_index))
answer.sort()
return answer
def split_pattern(pattern, wild_card):
indices = []
patterns = []
old_index = -1
tmp = ""
for i in range(len(pattern)):
if pattern[i] == wild_card and tmp:
indices.append(old_index)
patterns.append(tmp)
tmp = ""
old_index = -1
elif pattern[i] != wild_card:
old_index = i if old_index == -1 else old_index
tmp += pattern[i]
if tmp:
indices.append(old_index)
patterns.append(tmp)
return indices, patterns
def find_entries(text, pattern, wild_card):
result = []
occurrences = [0] * len(text)
entry_indices, patterns = split_pattern(pattern, wild_card)
entries = run_aho_corasick(text, patterns)
for index, pattern_index in entries:
text_idx = index - entry_indices[pattern_index]
if 0 <= text_idx < len(occurrences):
occurrences[text_idx] += 1
for i in range(len(occurrences) - len(pattern) + 1):
if occurrences[i] == len(patterns):
result.append(i + 1)
return result
if __name__ == "__main__":
text = input()
pattern = input()
wild_card = input()
answer = find_entries(text, pattern, wild_card)
for i in answer:
print(i)
