模式匹配的朴素算法是在匹配过程中,将模式串一位一位地往后移动。而更高效的KMP算法是在匹配过程中出现字符不相等时,模式串利用已经得到的“部分匹配表”结果将模式串向右滑动若干位,重新开始下一趟的匹配,例如对于主串“acabaabaabcac”,模式串“abaabcac”,利用KMP算法进行匹配的过程是:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
KMP算法工具
"""
class KPM_Matcher():
def __init__(self):
self.__measured_array = None
self.__target_array = None
def kmp_match(self, measured_array, target_array):
"""
kmp算法
:param measured_array:
:param target_array:
:return:
"""
self.__measured_array = len(measured_array)
self.__target_array = len(target_array)
table = self.partial_table(target_array)
cur = 0 #移动指针
while cur <= self.__measured_array - self.__target_array:
for i in range(self.__target_array):
if measured_array[i + cur] != target_array[i]:
cur += max(i - table[i-1], 1)
break
else:
return True
return False
def partial_table(self, target_array):
"""
部分匹配表
:param target_array:
:return:
"""
prefix = set()
postfix = set()
ret = [0]
for i in range(1, self.__target_array):
prefix.add(target_array[:i])
# print("pre:{}".format(prefix))
postfix = {target_array[j:i+1] for j in range(1, i+1)}
# print("post:{}".format(postfix))
ret.append(len((prefix & postfix or {''}).pop()))
# print(ret)
return ret
def naive_match(self, measured_array, target_array):
"""
朴素匹配算法,将字符串一位一位地往后移动进行匹配
:param measured_array:
:param target_array:
:return:
"""
self.__measured_array = len(measured_array)
self.__target_array = len(target_array)
for i in range(self.__measured_array - self.__target_array + 1):
if measured_array[i:i + self.__target_array] == target_array:
return True
return False
if __name__ == "__main__":
kmp = KPM_Matcher()
print(kmp.kmp_match("123456789","4545"))
print(kmp.naive_match("123456789","123"))