在经典的模式匹配问题中,我们给出了长度为n的文本字符串T和长度为m的模式字符P,并希望明确是否P是T的一个字串。如果是,则希望找到P在T中开始位置的最低索引j,比如T[j:j+m]和P匹配,或者从T中找到所有的P的开始位置索引。
在本文中,我们介绍三种匹配算法,难度依次递增。
1.暴力穷举法
穷举法是极其常用的一种算法,不止在匹配算法上,还在优化某些功能上也有涉及。
穷举法即为列举出所有的可能情况,并加以逐一判断。
def find_brute(T, P):
"""Return the lowest index of T at which substring P begins (or else -1)"""
n, m = len(T), len(P) # Get length of T and P's
for i in range(n-m+1): # Because it can't be P after T[n-m+1:]
k = 0 # Record the index of P
while k < m and T[i + k] == P[k]: # The match was incomplete and successful
k += 1
if k == m: # Match successful
return i
return -1
这是一个简单的暴力枚举的匹配算法,判断P是否是T的一个子串,是则返回第一次出现的索引,否则返回-1,算法优化在不改变代码结构的基础上,就是这里扣一点,那里扣一点。例如range函数的范围我们给出了n-m+1,因此对于P长度越大,则性能优化最大。
我们可以看到外层for循环至多执行了n-m+1次,内存while循环至多执行了m次,因此,该算法在最坏的情况下的运行时间是
测试一下:
T = "