详细描述求最长公共子序列算法

来源:互联网 发布:des算法加密过程 编辑:程序博客网 时间:2024/06/05 19:38

子序列与字串的区别:

子序列不要求公共部分在原字符串中连续,而字串要求连续。


动态规划求解

例子:"bdcaba", "abcbdab"  最长的公共子序列为 b c b a 和 b d a b


1:首先分析状态转移数组dp[i][j]的含义:

指的是 字符串 s1 从0到n-1 和 字符串 s2 从 0到m-1 的最大公共子序列的长度。

如上面dp[0][0]=0 因为 s1的“b” 和s2的'a"不相等,所以最大公共子序列的长度为0

dp[0][1]=1 因为 s1的“b” 和s2的'ab"有一个字母相等,所以最大公共子序列的长度为1

以此类推以此计算 到 dp[0][m-1],再计算dp[1][0]到dp[1][m-1].......到dp[n-1][m-1]。


2:计算过程

(1)计算dp[i][j]时,先比较s1.charAt(i)是否等于s2.charAt(j),如果等于,就把dp[i][j]的长度置为dp[i-1][j-1]+1,为什么是dp[i-1][j-1]+1呢?

因为当你的当前位置(i ,j)的对应字母相等时,最大长度就是上一次的最大长度加1,而上一次的最大长度就是dp[i-1][j-1]。比如:

当比较到 dp[2][2]时,即  字符串 s1 “bdc”和 字符串 s2 "abc" 的最大公共子序列的长度。因为s1.charAt(i)等于s2.charAt(j),所以最大长度要在上一次的最大长度上加一,而上一次指的就是“bd”和"ab"也就是i-1和j-1。


(2)如果不相等,那就要判断是少一个i的长度大些呢,还是少一个j的长度大些呢,也就是判断dp[i-1][j]和dp[i][j-1]哪个大,找出大的放进dp[i][j]。


(3)最大长度肯定是dp[n-1][m-1]。因为这是完整的两个串的最大子序列长度。


3:输出

(1)因为dp数组最后一个是最大的长度,所以就从最后一个开始回溯。


(2)比较s1.charAt(i)是否等于s2.charAt(j),如果等于就是输出该字母。


(3)不等于就判断dp[i-1][j]和dp[i][j-1]哪个大,如果dp[i-1][j]大,就到他的位置,也就是j不变,i-1;否则就相反。


(4)重复(2)(3)直到i<=1&&j<=1


4: 上面的思路用图表达就是把s1和s2弄成一个二维表


5:代码

public int[][] LCS(String s1,String s2){int dp[][] = new int[s1.length()+1][s2.length()+1];for (int i = 0; i <= s1.length(); i++) {dp[i][0] = 0;}for (int i = 0; i <= s2.length(); i++) {dp[0][i] = 0;}for (int i = 1; i <= s1.length(); i++) {for (int j = 1; j <= s2.length(); j++) {if(s1.charAt(i-1) == s2.charAt(j-1)){ //如果相等dp[i][j] = dp[i-1][j-1]+1;}else{if(dp[i-1][j]>dp[i][j-1]){dp[i][j]=dp[i-1][j];}else{dp[i][j]=dp[i][j-1];}}}}System.out.println("最长最序列长度:"+dp[s1.length()][s2.length()]);for (int i = 0; i < dp.length; i++) {for (int j = 0; j < dp[0].length; j++) {System.out.print(dp[i][j]+" ");}System.out.println();}System.out.println("-------输出-------------");int tempS1 = s1.length();int tempS2 = s2.length();while(tempS1>=1 && tempS2>=1){if(s1.charAt(tempS1-1)==s2.charAt(tempS2-1)){System.out.print(s2.charAt(tempS2-1)+" ");tempS1--;tempS2--;}else{if(dp[tempS1-1][tempS2]>dp[tempS1][tempS2-1]){tempS1--;}else{tempS2--;}}}return dp;}


1 0
原创粉丝点击