一、最长公共子序列
最长公共子序列的结构有如下表示:
设序列X=<x1, x2, …, xm>和Y=<y1, y2, …, yn>的一个最长公共子序列Z=<z1, z2, …, zk>,则:
- 若xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列;
- 若xm≠yn且zk≠xm ,则Z是Xm-1和Y的最长公共子序列;
- 若xm≠yn且zk≠yn ,则Z是X和Yn-1的最长公共子序列。
package dynamic_programming;
public class lcs0831 {
public static void main(String[] args)
{
String A="ABCDuiop";
String B="CBCEuiop";
int[][] strslen=new int[A.length()][B.length()];
for(int i=0;i<A.length();i++)
{
strslen[i][0]=0;
}
for(int j=0;j<B.length();j++)
{
strslen[0][j]=0;
}
if(A.charAt(0)==B.charAt(0))
{
strslen[0][0]=1;
}
else
{
strslen[0][0]=0;
}
for(int i=1;i<A.length();i++)
{
for(int j=1;j<B.length();j++)
{
if(A.charAt(i)==B.charAt(j))
{
strslen[i][j]=strslen[i-1][j-1]+1;
System.out.print(A.charAt(i));
}
else
{
strslen[i][j]=Math.max(strslen[i-1][j], strslen[i][j-1]);
}
}
}
System.out.print(strslen[A.length()-1][B.length()-1]);
}
}
输出为:BCuiop6
二、最长公共子串
package dynamic_programming;
public class LCSProblem {
public static void main(String[] args)
{
String A="ABCDuiopc";
String B="CBCEuiopb";
StringBuilder commsStr=new StringBuilder();
int bigest=0;
int x = 0,y=0;
int[][] strslen=new int[A.length()][B.length()];
for(int i=0;i<A.length();i++)
{
strslen[i][0]=0;
}
for(int j=0;j<B.length();j++)
{
strslen[0][j]=0;
}
if(A.charAt(0)==B.charAt(0))
strslen[0][0]=1;
else
{
strslen[0][0]=0;
}
for(int i=1;i<A.length();i++)
{
for(int j=1;j<B.length();j++)
{
if(A.charAt(i)==B.charAt(j))
{
strslen[i][j]=strslen[i-1][j-1]+1;
if(bigest<strslen[i][j])
{
bigest=strslen[i][j];
x=i; //x,y存储子串最后一个字母
y=j;
}
}
else
{
strslen[i][j]=0; //与最长公共子序列不同点:如果两个字母不相等,则赋值为0
}
}
}
System.out.println(bigest);
while(x>=0&&y>=0)
{
if(A.charAt(x)==B.charAt(y))
{
commsStr.append(A.charAt(x));
x--;
y--;
}
else
{
break;
}
}
System.out.println(commsStr.reverse());
}
}
输出结果为:
4
uiop