算法思路:对自身构造next数组,运用数组降低复杂度,统计与该前缀相同的个数(实际是自身对自身的查找)o(n)很强势
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+10; char b[maxn];int next_[maxn],num[maxn]; void getnext(int lenb) { for(int i=0;i<=lenb;i++) next_[i]=0; for(int i=1;i<=lenb;i++) { int j=next_[i]; while(j&&b[i]!=b[j]) j=next_[j]; next_[i+1]=(b[i]==b[j])?j+1:0; } } int main() { scanf("%s",&b); int len=strlen(b); getnext(len); for(int i=1;i<len;i++) num[next_[i]]++;//记录与next[i]-1相同字符的后缀个数 int flag=0;int n=next_[len]; while(n) { if(num[n]){ flag=1; break; } n=next_[n]; } if(flag==0) printf("Just a legend\n"); else { for(int i=0;i<n;i++) printf("%c",b[i]); printf("\n"); } return 0; }
算法思路:kmp模板
//kmp算法:判断一个字符串是否为另一个字符串的子序列 //维护next数组:这个数组表示的是最长前后缀相等的长度(除去最后一项) //注意next是用递推求解,next【j】是指的是长度 //此时匹配失败后,令当前字符的next继续进行匹配,此时已经保证next之前的项与当前字符的前几项相等 #include<bits/stdc++.h> using namespace std; string a,b;//a为主序列,b为需要判断的子序列 int next_[1000]; void getnext(int lenb) { for(int i=0;i<=lenb;i++) next_[i]=0; for(int i=1;i<=lenb;i++) { int j=next_[i]; while(j&&b[i]!=b[j]) j=next_[i]; next_[i+1]=(b[i]==b[j])?j+1:0; } } int main() { cin>>a>>b; int ans=0,j=0; int lena=a.size(),lenb=b.size(); for(int i=0;i<lena;i++) { while(j&&a[i]!=b[j]) j=next_[j]; if(a[i]==b[j]) j++; if(j==lenb) ans++,j=next_[j]; } cout<<ans<<endl; return 0; }