http://blog.sina.com.cn/s/blog_74e20d8901010pwp.html
我采用的是方法三。
注意:当长度相同时,取字典序最小的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> /* http://blog.sina.com.cn/s/blog_74e20d8901010pwp.html 我采用的是方法三。 注意:当长度相同时,取字典序最小的。 */ using namespace std; const int maxn=4005; char str[maxn][210]; int n; int minlen; //n个字符串中最短的长度 int id; //长度最短字符串的编号 int next[210]; void getNext(char*P){ int k; int lm=strlen(P); next[1]=0; k=0; for(int i=1;i<lm;i++){ while(k>0 && P[k]!=P[i]) k=next[k]; if(P[k]==P[i]) k++; next[i+1]=k; } } int kmp(char*T,char*P){ int k,c; c=0; //表示字符串P在T中能够匹配的最大长度 int ln=strlen(T),lm=strlen(P); for(int i=0;i<ln;i++){ while(k>0&&P[k]!=T[i]) k=next[k]; if(P[k]==T[i]) k++; if(k>c) c=k; if(k==lm) return k; } return c; } int main() { int l; while(scanf("%d",&n)!=EOF){ if(n==0) break; minlen=1000; for(int i=1;i<=n;i++){ scanf("%s",str[i]); l=strlen(str[i]); if(l<minlen){ minlen=l; id=i; } } char tmp[210],s[210]; int minl,maxl=0,cnt; //minl为枚举的后缀在其余n-1个字符串中都能匹配的长度 //maxl为公共子串的最大长度 char ans[210]; //所求公共子串 for(int i=1;i<=minlen;i++){ strncpy(tmp,str[id]+minlen-i,i); tmp[i]='