字符串、动态规划——最长公共子串LCS

题目描述:

求字符串S,T的最长公共子串

题目来源:http://blog.youkuaiyun.com/column/details/lf-algoritnote.html?&page=2


解法一:暴力搜索法

对两个字符串逐字符比较,找出以所有字符开始的最长子串中最长的。

public int LCS(String s1,String s2)
{
	int max=0;
	for(int i=0;i<s1.length()-max;i++)
	{
		for(int j=0;j<s2.length();j++)
		{
			int temp=0;
			while(temp+i<s1.length()&&temp+j<s2.length()&&s1.charAt(temp+i) == s2.charAt(temp+j))
				temp++;
			if(temp > max)
				max=temp;
		}
	}
	return max;
}


解法二:DP

字符串S,T所有前缀子串中的最长公共后缀,就是S,T的最长公共子串;(注:这里指的是前缀子串的后缀,而不是S,T的后缀!)

名词含义:

前缀子串:从字符串第一个字符开始的子串;

后缀:后缀是指从某个位置i开始到整个串末尾结束的一个特殊子串。字符串S的从i开头的后缀表示为Suffix( S,i) ,也就是Suffix( S, i) = S[ i:len ( S) ]。


在使用动态规划求解2个长度分别为p, q的字符串S,T的最长公共子串问题前,先给出求它们任意前缀子串对S[1:i],T[1:j]的最长公共后缀的算法,其中:1 ≤ i ≤ p,1 ≤ j ≤ q。设LCSuffix(S[1:i],T[1:j])表示前缀子串对S[1: i] ,T[1:j] 的最长公共后缀,则该问题的递推关系式如下:

 

       例如:字符串S“baba”, T“abab”, 使用上面递推关系式求得字符串S, T所有前缀子串对的最长公共后缀,如下表所示:

           字符串S, T所有前缀子串对应的最长公共后缀中长度最大的即为字符串S, T的最长公共子串,即:其中LCS( S,T) 表示字符串S, T的最长公共子串。对于字符串S“baba”, T“abab”,从表1中可以看出它们的最长公共后缀中长度最大为3,对应两个最长公共子串,即:"aba"和"bab"。 

//最长公共子串
	public void longsub(String s,String t)
	{
		String[][] dp=new String[s.length()+1][t.length()+1];//dp[i][j]存放s有i个字符,t有j个字符时的子串
		//初始化
		for(int i=0;i<=s.length();i++)
			dp[i][0]="";
		for(int j=0;j<=t.length();j++)
			dp[0][j]="";
		//general
		int max=0;
		String ss="";
		for(int i=1;i<=s.length();i++)
		{
			for(int j=1;j<=t.length();j++)
			{
				if(s.charAt(i-1) == t.charAt(j-1))
				{
					dp[i][j]=dp[i-1][j-1]+s.charAt(i-1);
					if(dp[i][j].length()>max)
					{
						max=dp[i][j].length();
						ss="";
					}
					if(dp[i][j].length() == max)
						ss=ss+"   "+dp[i][j];
				}
				else
					dp[i][j]="";
			}
		}
		System.out.println(""+max+" "+ss);
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值