📅  最后修改于: 2023-12-03 15:42:16.363000             🧑  作者: Mango
给定一个字符串和一个正整数k,找到字符串中长度为k的所有子串并打印出现次数至少为两次的子串。
本题可以采用哈希表来解决。我们首先定义一种将长度为k的子串转成数字的方法,可以将子串视为k进制的数字,各个字符对应k进制数位上的数。例如字符串"abc"对应的数字为20k^2+1k^1+2*k^0。
接下来,我们创建一个哈希表,将所有出现次数不小于2的子串加入到哈希表中,并统计它们出现的次数。然后遍历字符串,对于每个长度为k的子串,将其转成对应的数字,并在哈希表中查找。若存在,则出现次数加一,否则将该数字存入哈希表中并设置出现次数为1。
最后,我们遍历哈希表,找到出现次数不小于2的子串,打印出数字所对应的子串即可。
def find_repeated_substrings(s, k):
n = len(s)
k_pow = pow(26, k)
substr_to_count = {}
# 计算字符串s中每个长度为k的子串所对应的数字,并添加到哈希表中
for i in range(n - k + 1):
substr = s[i:i+k]
substr_num = 0
for j in range(k):
substr_num += (ord(substr[j]) - ord('a')) * pow(26, k - j - 1)
if substr_num in substr_to_count:
substr_to_count[substr_num] += 1
else:
substr_to_count[substr_num] = 1
# 遍历哈希表,找到出现次数不小于2的子串
repeated_substrings = []
for substr_num, count in substr_to_count.items():
if count >= 2:
repeated_substrings.append((count, "".join([chr((substr_num // k_pow**(k - j - 1)) % 26 + ord('a')) for j in range(k)])))
# 按出现次数从大到小排序,并打印结果
for count, substr in sorted(repeated_substrings, reverse=True):
print("{}: {}".format(substr, count))
# 测试代码
s = "ababcabab"
k = 3
find_repeated_substrings(s, k)
本题通过哈希表实现。需要注意的是,要将字符串转成整数,需要选取一个好的进制,否则有可能会出现哈希冲突。同时,当字符串较长时,可能会出现哈希冲突,因此还需要实现哈希表的冲突解决机制,这里可以采用链表的形式存储冲突的元素。