返回
字符串匹配算法巅峰对决:BF算法VS KMP算法
前端
2024-01-06 10:15:35
在计算机科学中,字符串匹配问题是一个非常重要的基础问题,也是算法领域研究的热点之一。所谓字符串匹配问题,就是寻找模式串在主串中的位置,如果存在则返回索引,否则返回-1。
解决字符串匹配问题的算法有很多,其中最简单、最直观的算法是BF算法,也称为暴力匹配算法。BF算法的原理非常简单:从主串的第一个字符开始,依次与模式串的第一个字符比较,如果相同则继续比较下一个字符,直到模式串的最后一个字符。如果在比较过程中发现不相同,则将模式串向右移动一个字符,然后从主串的当前位置重新开始比较。
虽然BF算法的原理简单,但其效率却非常低,因为在最坏的情况下,BF算法需要比较n*m次字符,其中n是主串的长度,m是模式串的长度。因此,BF算法只适用于处理短字符串的情况。
为了提高字符串匹配的效率,人们提出了KMP算法,KMP算法是一种改进的字符串匹配算法,其原理是利用模式串本身的特点来减少不必要的比较次数。KMP算法通过预处理模式串,构建一个next数组,next数组的每个元素代表了模式串中某个字符第一次出现的位置。在匹配过程中,如果主串的某个字符与模式串的某个字符不相同,则将模式串向右移动next[j]个字符,然后从主串的当前位置重新开始比较。
KMP算法的效率要比BF算法高很多,在最坏的情况下,KMP算法只需要比较n+m次字符。因此,KMP算法非常适合处理长字符串的情况。
下面是BF算法和KMP算法的详细示例代码:
def bf(main_str, pattern):
"""
暴力匹配算法
:param main_str: 主串
:param pattern: 模式串
:return: 匹配到的索引,否则返回-1
"""
main_len = len(main_str)
pattern_len = len(pattern)
for i in range(main_len - pattern_len + 1):
flag = True
for j in range(pattern_len):
if main_str[i+j] != pattern[j]:
flag = False
break
if flag:
return i
return -1
def kmp(main_str, pattern):
"""
KMP算法
:param main_str: 主串
:param pattern: 模式串
:return: 匹配到的索引,否则返回-1
"""
def get_next(pattern):
"""
获取next数组
:param pattern: 模式串
:return: next数组
"""
pattern_len = len(pattern)
next = [0] * pattern_len
i = 1
j = 0
while i < pattern_len:
if pattern[i] == pattern[j]:
j += 1
next[i] = j
i += 1
else:
if j > 0:
j = next[j-1]
else:
next[i] = 0
i += 1
return next
main_len = len(main_str)
pattern_len = len(pattern)
next = get_next(pattern)
i = 0
j = 0
while i < main_len and j < pattern_len:
if main_str[i] == pattern[j]:
i += 1
j += 1
else:
if j > 0:
j = next[j-1]
else:
i += 1
if j == pattern_len:
return i - pattern_len
return -1
if __name__ == '__main__':
main_str = 'hello world'
pattern = 'wor'
print(bf(main_str, pattern)) # 输出:6
print(kmp(main_str, pattern)) # 输出:6
以上就是字符串匹配问题中BF算法和KMP算法的详细介绍。希望本文对您有所帮助。