本文中所有的 string 建议换成 char*。
温馨提示,全是干货,证明从略。
问题是这样的:
两个字符串 AAA,BBB,求出 BBB 在 AAA 的所有出现。
例如:
A=abcdabcdabcdA=\texttt{abcdabcdabcd}A=abcdabcdabcd
B=abcdB=\texttt{abcd}B=abcd
那么 BBB 在 AAA 中一共有三个出现,分别是 000,444,和 888。
解法一:暴力
跟我说,暴力nb!
不用多说了,一位位匹配。
#include<bits/stdc++.h>
using namespace std;
int main()
{
string a,b;
cin>>a>>b;
for(int i=0;i<a.size()-b.size()+1;i++)
{
bool flag=true;
for(int j=0;j<b.size();j++)
if(a[i+j]!=b[j])
flag=false;
if(flag) printf("%d\n",i);
}
return 0;
}
时间复杂度 O(∣A∣∣B∣)O(|A||B|)O(∣A∣∣B∣)。
适用于比较小的数据。
解法二:KMP(1)
那么比较大的数据呢?
KMP!
KMP=Knuth+Morris+PrattKMP=Knuth+Morris+PrattKMP=Knuth+Morris+Pratt
该算法就是这三个人于 1997 年共同发布。
我们用两个指针 iii,jjj 表示 Ai−j+1...iA_{i-j+1...i}Ai−j+1...i 和 B1...jB_{1...j}B1...j 完全相等。当 Ai+1=Bj+1A_{i+1}=B_{j+1}A