《大话数据结构》一书第五章介绍了字符串的定义、存储结构和模式匹配算法。关于模式匹配,重点介绍了暴力(Brute-Force)算法和KMP算法,暴力算法较为简单,但性能较低。KMP算法在暴力算法基础上,通过特别巧妙的方式,降低了字符串比较次数,将时间复杂度从O((n-m+1)*m)
降低到了O(n+m)
。
但是!!!这本书中关于KMP算法的介绍冗长、混乱,讲解的不够透彻,只讲其一,不讲其二,非常不便于理解。在反复阅读和理解消化了几个小时后,发现对KMP算法还是不能了然于胸。
因此在网上查阅了相关资料,个人感觉讲的比较好的为:
鉴于上述两个回答讲解的非常透彻和简洁,此处对KMP算法的原理不做介绍。
下面是基于Python实现的代码。
def get_next(ps):
"""
基于KMP算法计算模式字符串的next值
:param ps: 模式字符串
:return: 返回nxt数组
eq: nxt = get_next('ababcd') # [-1, 0, 0, 1, 2, 0]
"""
i = 0
j = -1
# nxt数组表示的值含义为:当前位置左侧的字符串的前缀集和后缀集中字符相等的最大值
nxt = [-1] # 为便于程序计算,将位置0处的值设为-1
while i < len(ps):
if j == -1 or ps[i] == ps[j]:
i += 1
j += 1
nxt.append(j)
else:
j = nxt[j]
return nxt
def index_kmp(ts, ps):
"""
基于KMP算法实现字符串查找功能
:param ts: 主字符串
:param ps: 模板字符串
:return: 返回匹配位置或-1
"""
i = 0
j = 0
nxt = get_next(ps)
while i < len(ts) and j < len(ps):
if j == -1 or ts[i] == ps[j]:
i += 1
j += 1
else:
j = nxt[j]
if j == len(ps):
return i - j
else:
return -1
if __name__ == '__main__':
ts = 'abababdefab'
ps = 'ababd'
nxt = get_next(ps)
print(nxt)
idx = index_kmp(ts, ps)
if idx < 0:
print('字符串匹配未成功!')
else:
print('字符串匹配成功,匹配位置为:%s' % idx)
以上,欢迎交流指正~