http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4811
首先肯定是KMP。然后刚开始想的是每删一次,做一次kmp,但是那样肯定会超时,所以就想一种可以利用了之前kmp信息的数据结构,看了一下别人的报告,知道了
是栈这一种数据结构。然后每一次取出栈的最顶端就可以了。
关于kmp,在说几句。我自己的设置的next数组的信息是当,当前位匹配失效是 ,他应该跳到哪一位去继续匹配。
这里的当前位匹配失效指的是 s1当前位的下一位和s2的第i位不等。
View Code
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<stack> using namespace std; const int maxn=512010; char s1[maxn]; char s2[maxn]; int next[maxn]; int main() { int ans; while(scanf("%s%s",s1,s2)!=EOF) { int len1=strlen(s1); int len2=strlen(s2); stack<int>s; memset(next,0,sizeof(next)); next[0]=-1;//当第一位匹配失效是,跳到-1 ,即字符串的最左端外面 for(int i=1;i<len1;i++) { int pre=next[i-1];//算第i位时,已经知道前面的,pre要指向i-1位 while(pre!=-1&&s1[pre+1]!=s1[i]) pre=next[pre]; if(s1[pre+1]==s1[i])pre++;//一定是下一位相等,然后加1 next[i]=pre; } ans=0; for(int j=-1, i=0;i<len2;i++) { while(j>=0&&s1[j+1]!=s2[i]) j=next[j];//大于等于0就可以回退 if(s2[i]==s1[j+1])j++;//下一位相等 s.push(j); if(j==len1-1) { ans++; for(int t=0;t<len1;t++) s.pop(); if(!s.empty()) j=s.top(); else j=-1; } } cout<<ans<<endl; } return 0; }