数据结构与算法:python语言描述学习笔记Part4_kmp算法及改进

# -*- coding:utf-8 -*-

# 构造next数组函数
def gen_pnext(p):
i, k, m = 0, - 1, len(p)
pnext = [- 1]*m # 初始数组元素全为-1
while i < m- 1: # 生成下一个pnext元素值
if k == - 1 or p[i] == p[k]:
i, k = i+ 1, k+ 1
pnext[i] = k # 设置pnext元素
else:
k = pnext[k] # 退到更短相同前缀
return pnext

# KMP算法的改进
def gen_pnext_improve(p):
'''改进一点的版本,在下一跳字符和当前相同时,跳到下一跳的下一跳,跳的更远'''
i, k, m = 0, - 1, len(p)
pnext = [- 1] * m
while i < m- 1:
if k == - 1 or p[i] == p[k]:
i, k = i+ 1, k+ 1
if p[i] == p[k]:
pnext[i] = pnext[k]
else:
pnext[i] = k
else:
k = pnext[k]
return pnext

# 自己的神他喵麻烦构建next数组版本
def MINE_gen_pnext(p):
'''生成针对p中各个未知的i的下一跳位置表'''
pnext = [- 1, 0]
pnext=[]
count = 0
for j in range( 0, len(p)+ 1):
ps = p[ 0:j]
if ps == '':
continue
for i in range(len(ps), 1, - 1):
if ps[ 0: i- 1] == ps[-i+ 1:]:
pnext.append(len(ps[ 0: i- 1]))
if count<len(pnext):
count += 1
else:
pnext.append( 0)
count += 1
for i in range(len(pnext)- 1, 0, - 1):
pnext[i] = pnext[i- 1]
pnext[ 0] = - 1
return pnext

# kmp匹配主函数
def matching_KMP(t, p):
'''KMP Main fuction, t for target, p for pattern'''
i, j = 0, 0
n, m = len(t), len(p)
pnext = gen_pnext(p)
while j < n and i < m: # i == m说明找到了匹配
if i == - 1 or t[j] == p[i]: # 刚开始或者字符匹配时,考虑p中的下一字符
j, i = j+ 1, i+ 1
else: # 字符不匹配,则考虑pnext对应的下一字符
i = pnext[i]
if i == m: # 找到匹配,返回其下标
return j - i
return - 1 # 无匹配

print matching_KMP( 'ABCDEFG', 'EFG')

猜你喜欢

转载自blog.csdn.net/dmbjzhh/article/details/79532257
今日推荐