这三种算法都是最基本的字符串匹配算法
一、BF算法
BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和T的第二个字符;若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果。BF算法是一种蛮力算法。
代码实现
# -*- coding:UTF-8 -*-
'''
@Author:yzh
@Date:2022/11/13 16:13
'''
def BF(s, t):
i = 0
j = 0
while (i < len(s) and j < len(t)):
# 匹配成功
if (s[i] == t[j]):
i = i + 1
j = j + 1
else:
i = i - j + 1
j = 0
# 如果t字符串遍历完,说明找到匹配字串
if (j >= len(t)):
relt = i - len(t)
return "匹配字符串首地址为:%d" %relt
else:
return "未匹配到字符串"
if __name__ == "__main__":
a1 = "abcaaaabbbbcccabcbabdbcsbbbbnnn"
a2 = "ccabcba"
b = BF(a1, a2)
print(b)
s1 = "ababcabcacbab"
s2 = "abcac"
print(BF(s1, s2))
二、KMP算法
在理解KMP算法首先要明白next[ ]数组的含义,next[ i ]代表的含义是下标从1到i ii的字符串中前缀和后缀相等的最大长度,假如next[ i ]= j ,则p[ 1,j ]=p[ i - j + 1,i ]
当我们匹配到绿线的时候,我们文本串和模式串是完全匹配的,但是s [ i ] ! = p [ j + 1 ] ,所以接下来我们就要考虑将j指针移动到那个位置保证模式串的[ 1 , j ]和文本串的[ i − j , i − 1 ] 是完全匹配的,我们只需要将j移动到ne[j]的位置即可,(ne[j]表示的是紫色的那一段,含义就是1-j中前缀和后缀相等的最大长度)然后继续将s [ i ]与p [ j + 1 ]进行匹配,如果还是不能匹配的话,我们就重复上面的操作就行。
代码实现
# -*- coding:UTF-8 -*-
'''
@Author:yzh
@Date:2022/11/13 16:13
'''
def KMP(s, t):
if not s or not t:
return "输入字符串不能为空"
if len(t) > len(s):
return "模式字符串长度大于文本字符串长度,无法匹配"
# 构建部分匹配表
def build_partial_match_table(pattern):
table = [0] * len(pattern)
j = 0
for i in range(1, len(pattern)):
if pattern[i] == pattern[j]:
j += 1
table[i] = j
else:
if j > 0:
j = table[j - 1]
i -= 1
else:
table[i] = 0
return table
# 使用KMP算法进行匹配
i = 0
j = 0
table = build_partial_match_table(t)
while i < len(s) and j < len(t):
if s[i] == t[j]:
i += 1
j += 1
else:
if j > 0:
j = table[j - 1]
else:
i += 1
if j >= len(t):
return "匹配字符串首地址为:%d" % (i - len(t))
else:
return "未匹配到字符串"
if __name__ == "__main__":
a1 = "abcaaaabbbbcccabcbabdbcsbbbbnnn"
a2 = "ccabcba"
b = KMP(a1, a2)
print(b)
s1 = "ababcabcacbab"
s2 = "abcac"
print(KMP(s1, s2))