题目描述:
求字符串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);
}