多个字符串的公共最长连续子串(对两个字符串的扩展)

求两个字符串的最长连续公共子串用动态规划,参考http://blog.csdn.net/shandianling/article/details/7913818。存储空间是一个二维数组。

对于多个字符串也可用这个办法,求的是广义的对角线,存储空间是一个多维数组。

代码如下

import java.util.HashMap;
import java.util.Map;

public class Solution {
	
	public static void main(String[] args){
		System.out.println( new Solution().commonStrLen(new String[]{"abcdefg","abcde","cdef","defg"} ) );
	}
	
	//preKey是key的对角线
	public String commonStrLen(String[] strArray){
		String result;
		//公共子串的长度和strArray的结束为止
		int maxLength = 0;
		int endIndex = 0;
		
		//相当于是存放多维的矩阵,当值为0时不用存储,节省空间
		Map<String,Integer> multiArray = new HashMap<String,Integer>();
		
		int size = strArray.length;
		int totalSize = 1;
		
		//index代表strArray各元素的当前下标
		int[] index = new int[size];
		for(int i=0;i<size;i++){
			index[i] = 0;
			totalSize *= strArray[i].length();
		}
		int k = 0;
		if(totalSize==0)
			return "";
		else{
			while(k<totalSize){
				
				//得到字符
				char now = strArray[0].charAt(index[0]);
				boolean isEqual = true;
				for(int i=0;i<size;i++){
					if(now!=strArray[i].charAt(index[i]))
						isEqual = false;
				}
				
				//全部相等后
				if( isEqual ){
					String preKey = "";
					String key = "";
					for(int i=0;i<size;i++){
						preKey += index[i]-1;
						key += index[i];
					}
					if(multiArray.get(preKey)!=null)
					{
						multiArray.put(key, multiArray.get(preKey)+1);
						if(maxLength<multiArray.get(preKey)+1){
							maxLength = multiArray.get(preKey)+1;
							endIndex = index[0];
						}
					}
					else{
						multiArray.put(key, 1);
						if(maxLength<1){
							maxLength = 1;
							endIndex = index[0];
						}
					}
				}
				
				//注意下标的增长方式
				index[size-1] +=1;
				for(int i=size-1;i!=-1;i--){
					if(index[i]==strArray[i].length()){
						index[i] = 0;
						if(k!=totalSize-1)
							index[i-1] +=1;
					}
				}
				
				k++;
			}
			result = strArray[0].substring( endIndex+1-maxLength , endIndex+1 );
			return result;
		}
	}
	
}

时间复杂度为O(N1*N2*...),其中Ni表示第i个数组的长度。

还在探寻更好的算法。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值