最长的重复子序列 后缀数组 java实现

问题描述
给定一个字符串,求出其最长重复子串
例如:abcdabcd
最长重复子串是 abcd,最长重复子串可以重叠
例如:abcdabcda,这时最长重复子串是 abcda,中间的 a 是被重叠的。
后缀数组是一种数据结构,对一个字符串生成相应的后缀数组后,然后再排序,排完序依次检测相邻的两个字符串的开头公共部分。

abcbcab

0.abcbcab

1.bcbcab

2.cbcab

3.bcab

4.cab

5.ab

6.b

分成后缀数组

排序:(根据字典排序)

0.ab

1.abcbcab

2.b

3.bcab

4.bcbcab

5.cab

6.cbcab 

然后两两比较找出相同字符的长度

本例为: i(后缀数组下标)         temp(最大的相同数量,根据此数量截取)

            0(0-1数组比较以此类推)    2

            1                                  0

            2                                  1

            3                                  2

            4                                  0

            5(5-6数组比较)               1

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;


public class PostfixArray {
	public static void main(String[] args){
		String s = "abcbcab";
		System.out.println(maxLength(s));
	}
	
	public static List<String> maxLength(String s){
		Set<String> postfix = new TreeSet<String>();//存储后缀数组,并排序
		for(int i = 0; i < s.length(); i++){
			postfix.add(s.substring(i));
		}
		List<String> postfixList = new ArrayList<String>(postfix);//set转换成list方便调用
		int temp = 0;//最长的重复子序列截取位置
		
		for(int i = 0; i < postfixList.size() - 1; i++){//循环,找出最长的重复子序列下标,最长的重复子序列截取位置
			int len = maxlength(postfixList.get(i), postfixList.get(i + 1));//获取后缀数组两两比较的相同子序列长度
			if(len >= temp){
				temp = len;
				maxis = i;
			}
		}
		
		List<String> results = new ArrayList<String>();
		
		results.add(postfixList.get(maxis).substring(0, temp));//根据最长的重复子序列下标和截取位置,获得最长的重复子序列
		
		return results;
	}

	private static int maxlength(String next, String next2) {
		char[] c1 = next.toCharArray();
		char[] c2 = next2.toCharArray();
		int maxlen = 0;
		for(int i = 0; i < (c1.length > c2.length ? c2.length : c1.length); i++){
			if(c1[i] == c2[i]){
				maxlen++;
			}
		}
		return maxlen;
	}
}


你可能感兴趣的:(java,后缀数组,最长的重复子序列)