poj3080 (enumeration+kmp)

Click to open the question link


General meaning:

Multiple sets of data, each set of m strings, find the longest common substring of these strings. If the substring length is less than 3, output no significant commonalities.

If there are multiple longest common substrings (equal lengths), the one with the smallest lexicographical order is taken.


Idea: Take the first string as the reference standard, assuming its length is len, then it has len prefixes. The question is transformed into finding the remaining m-1 strings and the obtained

The longest common prefix of the len strings. At this time, the kmp template is directly applied, and pay attention to the understanding of the kmp algorithm. The kmp algorithm in the template is a pair

One, that is, a text string matches a pattern string. There are more than one here, you can find the longest matching length of each string and pattern string, in these values, find

The minimum value is sufficient. In the end, it is necessary to pay attention to special conditions, such as the substring length is less than 3, and the lexicographical order is the smallest when the length is equal.


code show as below:

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();
      }
	}

}


Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326934711&siteId=291194637