最长公共子序列
来源:互联网 发布:网络单机游戏 编辑:程序博客网 时间:2024/06/03 12:41
最长公共子序列
题目
最长公共子序列
思路
动态规划
序列str1和序列str2,长度分别为m和n;
- 创建1个二维数组L[m,n];
- 初始化L数组内容为0;
- m和n分别从0开始,m++,n++循环(两层循环):
- 如果str1[m] == str2[n],则L[m,n] = L[m - 1, n -1] + 1;
- 如果str1[m] != str2[n],则L[m,n] = max{L[m,n - 1],L[m - 1, n]}
- 最后从L[m,n]中的数字一定是最大的,且这个数字就是最长公共子序列的长度
- 从数组L中找出一个最长的公共子序列
从数组L中查找一个最长的公共子序列
i和j分别从m,n开始,递减循环(单层循环)直到i = 0,j = 0。其中,m和n分别为两个串的长度。- 如果str1[i] == str2[j],则将str[i]字符插入到子序列内,i–,j–;
- 如果str1[i] != str[j],则比较L[i,j-1]与L[i-1,j],L[i,j-1]大,则j–,否则i–;(如果相等,则任选一个)
说明:本段文字摘自最长公共子序列(LCS)问题,有部分修改
程序
package base;/** * description: * * @author liyazhou * @since 2017-10-16 16:47 */import org.junit.Test;import java.util.Arrays;/** 题目:最长公共子序列 思路: 动态规划 1、序列str1和序列str2 ·长度分别为m和n; ·创建1个二维数组L[m.n]; ·初始化L数组内容为0 ·m和n分别从0开始,m++,n++循环(两层循环): - 如果str1[m] == str2[n],则L[m,n] = L[m - 1, n -1] + 1; - 如果str1[m] != str2[n],则L[m,n] = max{L[m,n - 1],L[m - 1, n]} ·最后从L[m,n]中的数字一定是最大的,且这个数字就是最长公共子序列的长度 ·从数组L中找出一个最长的公共子序列 2、从数组L中查找一个最长的公共子序列 i和j分别从m,n开始,递减循环(单层循环)直到i = 0,j = 0。其中,m和n分别为两个串的长度。 ·如果str1[i] == str2[j],则将str[i]字符插入到子序列内,i--,j--; ·如果str1[i] != str[j],则比较L[i,j-1]与L[i-1,j],L[i,j-1]大,则j--,否则i--;(如果相等,则任选一个) 使用二维数组保存比较状态 [0, 0, 0, 0, 0, 0, 0, 0] [0, 0, 1, 1, 1, 1, 1, 1] [0, 0, 1, 1, 1, 2, 2, 2] [0, 0, 1, 2, 2, 2, 2, 2] [0, 1, 1, 2, 2, 2, 3, 3] [0, 1, 2, 2, 3, 3, 3, 4] [0, 1, 2, 2, 3, 3, 4, 4] */public class MaxCommonSeq { public String maxCommonSeq(String str1, String str2){ int[][] states = new int[str1.length()+1][str2.length()+1]; for (int i = 1; i < states.length; i ++){ char ch1 = str1.charAt(i-1); for (int j = 1; j < states[i].length; j ++){ char ch2 = str2.charAt(j-1); if (ch1 == ch2) states[i][j] = states[i-1][j-1] + 1; else states[i][j] = Math.max(states[i][j-1], states[i-1][j]); } } printArrs(states); int maxLen = states[states.length-1][states[0].length-1]; StringBuilder sBuilder = new StringBuilder(maxLen); for (int i = states.length-1, j = states[i].length-1 ; i > 0 && j > 0; ){ char ch1 = str1.charAt(i-1); char ch2 = str2.charAt(j-1); if (ch1 == ch2){ i --; j --; System.out.println(i + ", " + j); sBuilder.append(ch1); } else { if (states[i][j-1] > states[i-1][j]) j --; else i --; } } sBuilder = sBuilder.reverse(); return sBuilder.toString(); } @Test public void test(){ String[][] strs = { {"bdcaba", "abcbdab"}, }; for (String[] str : strs) System.out.println(maxCommonSeq(str[0], str[1])); } private void printArrs(int[][] arrs){ for (int[] arr : arrs) System.out.println(Arrays.toString(arr)); System.out.println(); }}
测试结果
[0, 0, 0, 0, 0, 0, 0, 0][0, 0, 1, 1, 1, 1, 1, 1][0, 0, 1, 1, 1, 2, 2, 2][0, 0, 1, 2, 2, 2, 2, 2][0, 1, 1, 2, 2, 2, 3, 3][0, 1, 2, 2, 3, 3, 3, 4][0, 1, 2, 2, 3, 3, 4, 4]4, 63, 51, 40, 3bdab
参考:
最长公共子序列(LCS)问题
阅读全文
1 0
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列...
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 第六周编程题_单词长度
- Android框架ButterKnife的使用详解,butterknife8.x.x版本的使用方法
- 用tomcat运行war包
- 查看tomcat进程,并删除进程
- 第十二天 PHP的数据类型转换
- 最长公共子序列
- 网站收藏
- Node.js+Express+MongoDB 建站实例——上传图片及其他模块
- 函数判断year是不是润年
- 用qt写tcp服务端和客户端界面遇到的问题及解决方法
- 罗湖探索破解无物业小区管理难题 11个小区率先试点
- [编程题]回文解码
- HDU 1181 Rank of Tetris
- 利用itext导出HTML到PDF,解决中文不显示和中文不换行的问题