详细描述求最长公共子序列算法
来源:互联网 发布: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;}
- 详细描述求最长公共子序列算法
- 【基础算法】求最长公共子序列
- 判断子序列、求最长公共子序列算法实现
- 求最长公共子序列
- 求公共最长子序列
- 求最长公共子序列
- 求最长公共子序列
- 求最长公共子序列
- 求最长公共子序列
- 求最长公共子序列
- 求最长公共子序列
- 求公共最长子序列
- 求最长公共子序列
- 线性空间求最长公共子序列的Nakatsu算法
- 算法实践-求最长公共子序列-动态规划
- 算法:最长公共子序列
- 最长公共子序列算法
- 【算法】最长公共子序列
- Android开发之路(二)--浅析MVC开发模式
- 设计模式——代理模式
- 如何禁止搜索引擎收录网站内容
- KE 时钟
- python简单爬虫例子(一)
- 详细描述求最长公共子序列算法
- 多进程、多线程、同步、通信
- C#实现多态之一抽象
- 莫队算法 sqrt(n)分块思想
- iOS开发 ----- 仿QQ实现滑动显示后边按钮
- A011-raw资源
- Wireless Network 并查集
- java中string与其他类型数据之类的转换
- USACO 1.3 Barn Repair (快排+贪心)