一、最长公共子序列
最长公共子序列的结构有如下表示:
设序列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