poj3080(枚举+kmp)

点击打开题目链接


大致题意:

多组数据,每组给定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();
      }
	}

}


猜你喜欢

转载自blog.csdn.net/lixiaomu2/article/details/71692551