字符串相关例题(查询子串在主串中的个数)
子串出现的次数
题目描述
给定两个字符串 s1 和 s2 ,求 s2 在 s1 中出现的次数,字符区分大小写,已匹配的字符不计入下一次匹配
输入输出描述
输入两行字符串,分别为s1和s2,s2的长度小于等于s1
输出s2在s1中出现的次数
示例1
输入:
ABCsdABsadABCasdhjabcsaABCasd
ABC
输出:
3
示例2
输入:
AAAAAAAA
AAA
输出:
2
解题代码
1.遍历解法
def solve(s1,s2):if s1=="" and s2=="":return 1elif s1!="" and s2=="":return 0elif s1=="" and s2!="":return 0i=0count=0while i<len(s1):j=ik=0if s1[i]==s2[0]:j+=1k+=1while j<len(s1) and k<len(s2):if s1[j]==s2[k]:j+=1k+=1else:if k==len(s2):count+=1i=jif j==len(s1):return countelse:i+=1return counts1=input()
s2=input()
print(solve(s1,s2))
2.滑动窗口结合字符串切片
def solve(s1,s2):#可以判断子串是否为空,根据题目if not s2:return "子串为空"#判断是否子串长于主串if len(s1)<len(s2):return "子串长于主串"i=0count=0while i<len(s1)-len(s2):if s1[i:i+len(s2)]==s2:count+=1i+=len(s2)else:i+=1return counts1=input()
s2=input()
print(solve(s1,s2))
3.kmp算法
def count_substrings_kmp(s1, s2):# 特殊情况处理if not s2:return 0len1, len2 = len(s1), len(s2)if len2 > len1:return 0# 步骤1:构建LPS数组(最长公共前后缀数组)def build_lps(pattern):lps = [0] * len(pattern)length = 0 # 记录当前最长公共前后缀的长度i = 1while i < len(pattern):if pattern[i] == pattern[length]:length += 1lps[i] = lengthi += 1else:if length != 0:# 回溯到上一个可能的匹配位置length = lps[length - 1]else:lps[i] = 0i += 1return lpslps = build_lps(s2)count = 0i = 0 # i遍历s1j = 0 # j遍历s2while i < len1:if s1[i] == s2[j]:i += 1j += 1# 匹配成功一次if j == len2:count += 1j = 0 # 重置s2指针,寻找下一个非重叠匹配# 注意:此处i已自动跳过当前匹配的子串(因i在匹配时递增)# 匹配失败时的处理elif i < len1 and s1[i] != s2[j]:if j != 0:# 根据LPS数组回溯j,避免重复比较j = lps[j - 1]else:# j=0时直接移动ii += 1return count# 读取输入
s1 = input().strip()
s2 = input().strip()# 输出结果
print(count_substrings_kmp(s1, s2))