Posted on:
Last modified:
解决两个字符串的动态规划问题,一般都是用两个指针 i,j 分别指向两个字符串的最后,然后一步步往前走,缩小问题的规模。
解字符串问题常用的算法是采用滑动窗口的方法。
避免字符串 O(n) 比较的一个方法是使用 hash。
字符串问题本质上都是自动机问题,实际上还是图论问题。
j = next[j-1]
def kmp(t, p):
"""return all matching positions of p in t"""
next = [0]
j = 0 # j 表示当前自创中前缀和后缀匹配的最大长度
# 注意这里是从 1 开始
for i in range(1, len(p)):
while j > 0 and p[i] != p[j]:
j = next[j - 1] # 关键之处
if p[i] == p[j]: # 相等时,最大匹配自然要 +1
j += 1
next.append(j)
ans = []
j = 0
for i in range(len(t)):
while j > 0 and t[i] != p[j]:
j = next[j - 1] # 关键之处
if t[i] == p[j]:
j += 1
if j == len(p):
ans.append(i - (j - 1))
# 这里是匹配成功了,但是要接着找下一个,所以按失败处理
j = next[j - 1]
return ans
def test():
p1 = "aa"
t1 = "aaaaaaaa"
assert(kmp(t1, p1) == [0, 1, 2, 3, 4, 5, 6])
p2 = "abc"
t2 = "abdabeabfabc"
assert(kmp(t2, p2) == [9])
p3 = "aab"
t3 = "aaabaacbaab"
assert(kmp(t3, p3) == [1, 8])
print("all test pass")
if __name__ == "__main__":
test()
Trie 是一个自动机,KMP 是一个自动机,AC 自动机是 Trie 上运行 KMP 得到的自动机。Trie 和 KMP 都可以用于单模匹配,AC 自动机可以用于多模匹配。AC 自动机是确定性有限状态自动机 (DFA)。
正则表达式构建出来的却是一个非确定性有限状态自动机(NFA),非确定指的是跳转的时候可能有多个分支。要实现非指数时间解,也就是不用回溯,其实就是把回溯的深度优先遍历改成了广度优先遍历从而实现了剪枝。
https://juejin.im/post/5d1c7df2e51d45775c73dd49
© 2016-2022 Yifei Kong. Powered by ynotes
All contents are under the CC-BY-NC-SA license, if not otherwise specified.
Opinions expressed here are solely my own and do not express the views or opinions of my employer.
友情链接: MySQL 教程站