hdu 1238
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1238
题意:找出给出所有字符串中相同的最长子串。可以反向查找。
有两种做法:
1、利用stl的string,直接进行暴力。
2、用扩展kmp,直接找ext数组。
#include<cstdio> #include<iostream> #include<string> #include<algorithm> using namespace std; string str[106]; int main() { int T; cin >> T; while(T--){ int n; cin >> n; int len=202,under; for(int i=1;i<=n;i++){ cin >> str[i]; if(len>str[i].size()){ len=str[i].size(); under=i; } } int ans=0; for(int i=len;i>0;i--){ for(int j=0;j<len-i+1;j++){ string s1,s2; int flag=0; s1=str[under].substr(j,i); s2=s1; reverse(s2.begin(),s2.end()); for(int k=1;k<=n;k++){ if(str[k].find(s1)==string::npos&&str[k].find(s2)==string::npos){ flag=1; break; } } if(!flag){ if(ans<s1.size()) ans=s1.size(); } } if(ans!=0) break; } printf("%d\n",ans); } return 0; }
poj 3080有用到过substr分割子串。现在在用一个reverse取反子串。
#include<cstdio> #include<cstring> #include<iostream> #include<string> #include<algorithm> using namespace std; const int maxn=505; int nxt[105][maxn],ext[105][maxn]; char s[105][maxn]; int len[105],ans[maxn]; void exkmp(char s[],char t[],int lens,int lent,int c){ int i,j,p,l,k; nxt[c][0]=lent;j=0; while(j+1<lent&&t[j]==t[j+1]) j++; nxt[c][1]=j; k=1; for(i=2;i<lent;i++){ if(i+nxt[c][i-k]<nxt[c][k]+k) nxt[c][i]=nxt[c][i-k]; else{ j=max(0,nxt[c][k]+k-i); while(i+j<lent&&t[i+j]==t[j]) j++; nxt[c][i]=j; k=i; } } j=0; while(j<lens&&j<lent&&s[j]==t[j]) j++; ext[c][0]=j; k=0; for(i=1;i<lens;i++){ if(nxt[c][i-k]+i<ext[c][k]+k) ext[c][i]=nxt[c][i-k]; else{ j=max(0,ext[c][k]+k-i); while(i+j<lens&&j<lent&&s[i+j]==t[j]) j++; ext[c][i]=j; k=i; } } } int main() { int T; scanf("%d",&T); while(T--){ memset( ans, 0x3f, sizeof ans); int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",s[i]); for(int i=1;i<=n;i++) len[i]=strlen(s[i]); s[1][len[1]]='#'; for(int i=1;i<=len[1];i++) s[1][len[1]+i]=s[1][len[1]-i]; s[1][len[1]+len[1]+1]=0; len[1]=strlen(s[1]); int maxx=0; for(int i=0;i<len[1];i++){ for(int j=2;j<=n;j++){ int cnt=0; exkmp(s[j],s[1]+i,len[j],len[1]-i,j); for(int k=0;k<len[j];k++){ if(ext[j][k]>cnt) cnt=ext[j][k]; } if(cnt<ans[i]) ans[i]=cnt; } if(ans[i]>maxx) maxx=ans[i]; } printf("%d\n",maxx); } return 0; }
这里就用扩展kmp直接找ext函数。