📌  相关文章
📜  给定字符串中连续出现的不同子字符串的计数(1)

📅  最后修改于: 2023-12-03 15:11:39.823000             🧑  作者: Mango

给定字符串中连续出现的不同子字符串的计数

在字符串处理中,有时需要统计给定字符串中连续出现的不同子字符串的数量。这个问题可以用一些简单的算法来解决。下面介绍两种常见的实现方法。

方法一:使用哈希表

哈希表是一种常用的数据结构,可以用来快速查找和插入元素。在这个问题中,我们可以使用哈希表来记录已经出现的子字符串,从而避免重复计数。

具体实现流程如下:

  1. 定义一个空的哈希表 dict,用来记录已经出现的子字符串。
  2. 定义两个指针 i 和 j,初始值都为 0。
  3. 当 j < len(s) 时,执行以下操作:
    • 从 s[j] 开始向后逐个字符遍历,直到出现一个与前面字符不同的字符为止。设这个字符的下标为 k。
    • 如果 k 不在 dict 中,说明从 i 到 j 的子字符串是一个新的子字符串,可以将它加入 dict 中,并将计数器加 1。
    • 如果 k 在 dict 中,说明从 i 到 j 的子字符串已经在之前出现过,可以直接继续向后遍历。
    • 将 i 设为 k,将 j 后移一位,继续遍历。

代码如下:

def count_substrings(s: str) -> int:
    count = 0
    dict = {}
    i, j = 0, 0
    while j < len(s):
        while j < len(s) and s[j] == s[i]:
            j += 1
        if j - i not in dict:
            dict[j - i] = True
            count += 1
        i, j = j, j + 1
    return count
方法二:前缀和

前缀和是一种常用的技巧,可以用来快速求出一段区间的和。在这个问题中,我们可以使用前缀和来统计连续子字符串的数量。

具体实现流程如下:

  1. 定义一个数组 prefix,长度为 len(s),用来记录以每个字符结尾的不同子字符串的数量。
  2. 初始化 prefix[0] = 1。
  3. 当 i > 0 时,执行以下操作:
    • 从 s[i] 开始向前逐个字符遍历,直到出现一个与前面字符不同的字符为止。设这个字符的下标为 j。
    • 将 prefix[i] 设为 prefix[j - 1] + (i - j + 1)。
    • 将计数器加上 prefix[i]。

代码如下:

def count_substrings(s: str) -> int:
    count = 0
    prefix = [0] * len(s)
    prefix[0] = 1
    for i in range(1, len(s)):
        j = i - 1
        while j >= 0 and s[j] != s[i]:
            j -= 1
        if j < 0:
            prefix[i] = 1
        else:
            prefix[i] = prefix[j] + (i - j)
        count += prefix[i]
    return count

以上是两种常见的实现方法,可以根据自己的喜好选择其中一种来解决这个问题。