大致题意:
多组数据,每组给定m个字符串,求这些字符串最长公共子串。若子串长度小于3,则输出no significant commonalities。
若有多个最长公共子串(长度相等),则取其中字典序最小的那个。
思路:以第一个字符串为参考标准,假设其长为len,则其有len个前缀。题目就转化为求剩余m-1个字符串与得到的
这len个字符串的最长公共前缀。这个时候就直接套用kmp模板了,注意kmp算法的理解。模板里面kmp算法是一对
一的,即一个文本串与一个模式串匹配。这里有多个,可以求出每个字符串与模式串最长匹配长度,这些数值里求
最小值即可。做到最后还是要注意特殊条件,比如子串长度小于3,以及长度相等求字典序最小。
代码如下:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.StringTokenizer; class Reader{ static BufferedReader reader; static StringTokenizer tokenizer; static void init(InputStream input) { reader=new BufferedReader(new InputStreamReader(input)); tokenizer=new StringTokenizer(""); } static String next() throws IOException{ while (!tokenizer.hasMoreTokens()) { tokenizer=new StringTokenizer(reader.readLine()); } return tokenizer.nextToken(); } static int nextInt() throws IOException{ return Integer.parseInt(next()); } } public class Main { /** * @param args */ static int t,m,maxlen,nowlen,len,reslen; static String str; static char chs[][]; static char ans[],nowch[]; static int f[]; static boolean bo; private static void dealans() { if (reslen>len) { len=reslen; for (int i=0;i<reslen;i++) ans[i]=nowch[i]; } else if (reslen==len){ bo=true; for (int i=0;i<len;i++) if (nowch[i]>ans[i]){ bo=false; break; } else if (nowch[i]<ans[i]) { bo=true; break; } if (bo) { for (int i=0;i<len;i++) ans[i]=nowch[i]; } } } private static void deal(){ maxlen=chs[0].length; ans=new char[maxlen]; int k,max,min; boolean flag=true; boolean bo; len=0; for (int i=1;i<=maxlen;i++) { nowlen=maxlen-i+1; nowch=new char[nowlen]; for (int j=i;j<=maxlen;j++) nowch[j-i]=chs[0][j-1]; f=new int[nowlen+1]; f[1]=0; k=0; for (int j=1;j<nowlen;j++) { while ((k!=0)&&(nowch[j]!=nowch[k])) k=f[k]; if (nowch[j]==nowch[k]) k++; f[j+1]=k; } flag=true; min=Integer.MAX_VALUE; for (int l=1;l<m;l++) { k=0; max=0; for (int n=0;n<chs[l].length;n++) { while ((chs[l][n]!=nowch[k])&&(k!=0)) k=f[k]; if (chs[l][n]==nowch[k]) k++; if (k>max) max=k; if (k==nowlen) break; } if (max<min) min=max; } reslen=min; dealans(); } if (len<3) { System.out.println("no significant commonalities"); return; } else { for (int i=0;i<len;i++) System.out.print(ans[i]); System.out.println(); } } public static void main(String[] args) throws IOException { // TODO Auto-generated method stub Reader.init(System.in); t=Reader.nextInt(); for (int casenum=1;casenum<=t;casenum++) { m=Reader.nextInt(); chs=new char[m][]; for (int i=0;i<m;i++) { str=Reader.next(); chs[i]=str.toCharArray(); } deal(); } } }