📅  最后修改于: 2023-12-03 15:35:51.778000             🧑  作者: Mango
在编程中,我们有时需要统计一个字符串中出现另一个字符串(子串)的次数。本文将介绍几种算法实现方法,并给出示例代码。
暴力枚举法是最朴素的方法。它的思路是依次枚举源字符串中每一个字符,再以该字符为起点,比较源字符串和目标字符串是否匹配。如果匹配成功,则计数器加一。该方法的时间复杂度为O(n*m),其中n表示源字符串长度,m表示目标字符串长度。
示例代码:
def count_substr(string, target):
count = 0
for i in range(len(string)):
if string[i:i + len(target)] == target:
count += 1
return count
KMP算法是一种高效的字符串匹配算法,它的时间复杂度为O(n+m),其中n表示源字符串长度,m表示目标字符串长度。它采用了动态规划的思想,在匹配时避免了不必要的重复计算。
示例代码:
def count_substr(string, target):
def kmp_table(pattern):
table = [0] * len(pattern)
k = 0
for i in range(1, len(pattern)):
while k > 0 and pattern[k] != pattern[i]:
k = table[k-1]
if pattern[k] == pattern[i]:
k += 1
table[i] = k
return table
count = 0
table = kmp_table(target)
i, j = 0, 0
while i < len(string):
if string[i] == target[j]:
i += 1
j += 1
if j == len(target):
count += 1
j = table[j-1]
else:
if j > 0:
j = table[j-1]
else:
i += 1
return count
Boyer-Moore算法是一种比KMP更加高效的字符串匹配算法,它的时间复杂度为O(n),其中n表示源字符串长度。它采用了两种启发式策略:坏字符规则和好后缀规则,在匹配时避免了大量的重复比较。
示例代码:
def count_substr(string, target):
def bm_table(pattern):
table = [-1] * 256
for i in range(len(pattern)):
table[ord(pattern[i])] = i
return table
count = 0
table = bm_table(target)
n, m = len(string), len(target)
i = m - 1
while i < n:
j = m - 1
while j >= 0 and string[i] == target[j]:
i -= 1
j -= 1
if j == -1:
count += 1
i += m * 2 - 1
else:
i += max(m - 1 - j, 1) + m - table[ord(string[i])]
return count
以上三种方法都可以实现在源字符串中统计目标字符串出现的次数。具体采用哪种方法,应根据实际情况选择。在优化程序性能时,可以考虑选择Boyer-Moore算法。