[python刷题模板] AC自动机/字符串多模式匹配
一、 算法&数据结构
1. 描述
ac自动机可以用O(L+N)的时间匹配出所有正文text中的、字典里所有存在的串。
- AC自动机是trie+kmp的一个数据结构。
- 核心是给每个节点建立
失败指针:fail
,类似kmp里的next,当模式串匹配失败时,直接跳到下一个位置,而不是暴力的向后错一个位置。 - 写法需要把26个字母全init,因此其实我有些怀疑用字典写法是否比数组强。
- 由于背不过,还是搞个板子CV一下吧。
- 注:本文未完,早上时间紧,等我多找几个例题,把自动机提成类再改改。
2. 复杂度分析
- 初始化, O(L)
- 查询,O(N)
3. 常见应用
- 一大篇文章的多模式匹配。
- 在线字符流的多模式匹配。
4. 常用优化
- py当然要用字典啦。
二、 模板代码
1. 在线匹配正文字符流
例题: 1032. 字符流
- 在线顺序向后匹配,实际上就是遍历text的过程。
class StreamChecker:
def __init__(self, words: List[str]):
self.trie = {}
for w in words:
cur = self.trie
for c in w:
if c not in cur:
cur[c] = {}
cur = cur[c]
cur['#'] = w
cur = self.trie
cur['fl'] = cur
q = deque()
for c in ascii_lowercase:
if c in cur:
cur[c]['fl'] = cur
q.append(cur[c])
else:
cur[c] = cur
while q:
cur = q.popleft()
if '#' not in cur and '#' in cur['fl']:
cur['#'] = cur['fl']['#']
for c in ascii_lowercase:
if c in cur:
cur[c]['fl'] = cur['fl'][c]
q.append(cur[c])
else:
cur[c] = cur['fl'][c]
self.cur = self.trie
def query(self, letter: str) -> bool:
self.cur = self.cur.get(letter)
return '#' in self.cur