数据结构与算法之数据结构 字符串匹配 KMP/Boyer Moore 算法

数据结构与算法阿木 发布于 5 天前 2 次阅读


字符串匹配算法:KMP与Boyer-Moore算法详解

字符串匹配是计算机科学中一个基础且重要的问题。在许多应用场景中,如文本编辑、搜索引擎、生物信息学等,都需要对字符串进行高效的匹配。本文将围绕字符串匹配这一主题,详细介绍两种经典的算法:KMP(Knuth-Morris-Pratt)算法和Boyer-Moore算法。

KMP算法

KMP算法是一种高效的字符串匹配算法,由Donald Knuth、James H. Morris和Vijay R. Pratt共同提出。KMP算法的核心思想是避免重复扫描已经匹配的字符,从而提高匹配效率。

KMP算法的基本原理

KMP算法通过构建一个部分匹配表(也称为“失败函数”或“next数组”),来记录模式串中每个位置之前的最大公共前后缀的长度。当发生不匹配时,可以利用这个信息跳过一些不必要的比较,从而提高匹配效率。

KMP算法的实现

以下是一个KMP算法的Python实现:

python

def kmp_search(text, pattern):


构建部分匹配表


def build_next(pattern):


next = [0] len(pattern)


k = 0


for i in range(1, len(pattern)):


while k > 0 and pattern[k] != pattern[i]:


k = next[k - 1]


if pattern[k] == pattern[i]:


k += 1


next[i] = k


return next

next = build_next(pattern)


i = j = 0


while i < len(text):


if pattern[j] == text[i]:


i += 1


j += 1


if j == len(pattern):


return i - j


elif i < len(text) and pattern[j] != text[i]:


if j != 0:


j = next[j - 1]


else:


i += 1


return -1

示例


text = "ABABDABACDABABCABAB"


pattern = "ABABCABAB"


print(kmp_search(text, pattern)) 输出:10


Boyer-Moore算法

Boyer-Moore算法是一种高效的字符串匹配算法,由Robert S. Boyer和J. Strother Moore共同提出。Boyer-Moore算法的核心思想是利用已知的模式串信息,从后往前进行匹配,从而减少不必要的比较。

Boyer-Moore算法的基本原理

Boyer-Moore算法包含两个阶段:坏字符规则和好后缀规则。

- 坏字符规则:当发生不匹配时,如果当前字符不是模式串的最后一个字符,则将模式串向右滑动,直到找到一个匹配的字符或者模式串的末尾。

- 好后缀规则:如果当前字符是模式串的最后一个字符,则检查模式串的末尾是否与文本的末尾匹配。如果匹配,则将模式串向右滑动;如果不匹配,则根据好后缀规则确定滑动距离。

Boyer-Moore算法的实现

以下是一个Boyer-Moore算法的Python实现:

python

def boyer_moore_search(text, pattern):


构建坏字符表


def build_bad_char_table(pattern):


bad_char = [-1] 256


for i in range(len(pattern) - 1):


bad_char[ord(pattern[i])] = i


return bad_char

构建好后缀表


def build_good_suffix_table(pattern):


n = len(pattern)


suffix = [0] n


l = [0] n


i = n - 1


j = n


while i > 0:


while j > 0 and pattern[i - 1] != pattern[j - 1]:


if suffix[j] == 0:


suffix[j] = i


j = suffix[j]


i -= 1


j -= 1


k = 0


i = 0


while i < n:


if suffix[i] == 0:


l[i] = k


i += 1


k += 1


else:


j = suffix[i]


k = max(0, k - 1)


while j > 0 and pattern[i - 1] != pattern[j - 1]:


if suffix[j] == 0:


suffix[j] = i


j = suffix[j]


i += 1


j += 1


return l

bad_char = build_bad_char_table(pattern)


good_suffix = build_good_suffix_table(pattern)


i = len(pattern) - 1


j = len(pattern) - 1


while i < len(text):


if text[i] == pattern[j]:


i -= 1


j -= 1


if j < 0:


return i - j


elif bad_char[ord(text[i])] > j:


i = i - j - bad_char[ord(text[i])]


j = len(pattern) - 1


else:


j = good_suffix[j]


return -1

示例


text = "ABABDABACDABABCABAB"


pattern = "ABABCABAB"


print(boyer_moore_search(text, pattern)) 输出:10


总结

本文详细介绍了两种经典的字符串匹配算法:KMP算法和Boyer-Moore算法。KMP算法通过构建部分匹配表来避免重复扫描,而Boyer-Moore算法则通过坏字符规则和好后缀规则来减少不必要的比较。这两种算法在处理字符串匹配问题时具有很高的效率,在实际应用中得到了广泛的应用。