数据结构 - 字符串 - 最长公共子序列 + 最长公共子字符串 - 动态规划
生活随笔
收集整理的這篇文章主要介紹了
数据结构 - 字符串 - 最长公共子序列 + 最长公共子字符串 - 动态规划
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最長公共子序列
/*** 最長公共子序列* 參考鏈接:http://blog.csdn.net/biangren/article/details/8038605* Created by 18710 on 2017/8/24.*/ public class LongestCommonSubsequence {public static void main(String[] args) {char[] x = {'A', 'B', 'C', 'B', 'D', 'A', 'B'};char[] y = { 'B', 'D', 'C', 'A', 'B', 'A'};int[][] direction = getLongestCommonSubsequence(x, y);getLongestCommonSubsequence(direction, x, x.length - 1, y.length - 1);}/*** 動態規劃:狀態為目前的最長子序列長度* lcs[i][j] = 0; if i == 0 || j == 0* lcs[i][j] = lcs[i-1][j-1] + 1; if x[i]=y[j]* lcs[i][j] = lcs[i][j-1]; if x[i]!=y[j] && lcs[i][j-1] > lcs[i-1][j]* lcs[i][j] = lcs[i-1][j]; if x[i]!=y[j] && lcs[i][j-1] < lcs[i-1][j]* 具體流程參考 img文件夾下的 LongestCommonSubsequence.img* @param x 第一個字符串* @param y 第二個字符串* @return 最長子序列的遍歷方向*/public static int[][] getLongestCommonSubsequence(char[] x, char[] y) {if (x == null || y == null || x.length == 0 || y.length == 0) {return null;}// 長度為原來的長度加1,因為第一行和第一列的值都是空,這樣動態規劃的時候省去判斷第一行然后i-0小于0的情況int[][] lcs = new int[x.length + 1][y.length + 1]; // 保存最長子序列的長度int[][] direction = new int[x.length + 1][y.length + 1]; // 保存搜索方向for (int i = 0; i < x.length; i++) {for (int j = 0; j < y.length; j++) {if (x[i] == y[j]) {lcs[i + 1][j + 1] = lcs[i][j] + 1; // 相等公共子序列長度加1direction[i + 1][j + 1] = 1; // 1表示左上角對角線移動} else if (lcs[i][j + 1] >= lcs[i + 1][j]) { /** 注意條件是大于等于*/lcs[i + 1][j + 1] = lcs[i][j + 1]; // 上邊的元素值較大direction[i + 1][j + 1] = 0; // 0表示上移動} else {lcs[i + 1][j + 1] = lcs[i + 1][j]; // 左邊的元素值較大direction[i + 1][j + 1] = -1; // -1表示左移動}}}return direction;}/***根據最長子序列的方向打印子序列* @param direction 方向數組* @param x 第一個或者第二個字符串* @param i 橫坐標* @param j 縱坐標*/public static void getLongestCommonSubsequence (int[][] direction, char[] x, int i, int j) {if (i < 0 || j < 0) { // 第一行為空return ;}if (direction[i + 1][j + 1] == 1) { // 1表示左上角getLongestCommonSubsequence(direction, x, i - 1, j - 1);System.out.print(x[i] + " ");} else if (direction[i + 1][j + 1] == 0) { // 0表示上移動getLongestCommonSubsequence(direction, x, i - 1, j);} else if (direction[i + 1][j + 1] == -1){ // -1表示左移動getLongestCommonSubsequence(direction, x, i, j - 1);}}}最長公共子串
動態規劃:求得最長子串長度和最后一個相同字符的下標即可
/*** 最長公共子串* 動態規劃:求的最長子串長度和最后一個相同字符的下標即可* 參考鏈接:http://blog.csdn.net/hackbuteer1/article/details/6686931** Created by 18710 on 2017/8/24.*/ public class LongestCommonSubstring {public static void main(String[] args) {char[] x = {'A', 'B', 'C', 'D',};char[] y = { 'C', 'A', 'B', 'E'};getLongestCommonSubstring(x, y);}/*** 動態規劃:狀態為目前的最長子串長度* lcs[i][j] = 0; if i == 0 || j == 0 || x[i]!=y[j]* lcs[i][j] = lcs[i-1][j-1] + 1; if x[i]=y[j]* @param x 第一個字符串* @param y 第二個字符串* @return*/public static void getLongestCommonSubstring(char[] x, char[] y) {if (x == null || y == null || x.length == 0 || y.length == 0) {return ;}int max = 0; // 最長公共子串的長度int lastX = 0; // 第一個字符串 最長公共子串最后一個字符的數組下標// 長度為原來的長度加1,因為第一行和第一列的值都是空,// 這樣動態規劃的時候省去判斷第一行然后i-0小于0的情況int[][] lcs = new int[x.length + 1][y.length + 1]; // 保存最長子序列的長度for (int i = 0; i < x.length; i++) {for (int j = 0; j < y.length; j++) {if (x[i] == y[j]) {lcs[i + 1][j + 1] = lcs[i][j] + 1; // 相等公共子序列長度加1} else {lcs[i + 1][j + 1] = 0; // 左邊的元素值較大}if (lcs[i + 1][j + 1] > max) { // 更新最長子串的長度和兩個子串對應的下標max = lcs[i + 1][j + 1];lastX = i;}}}System.out.println("最長子串長度為:" + max + ",下標為:" + lastX);StringBuffer sb = new StringBuffer(); // 保存最長公共子串while (max-- > 0) {sb.append(x[lastX--]);}System.out.println(sb.reverse().toString()); // 逆序打印}}總結
以上是生活随笔為你收集整理的数据结构 - 字符串 - 最长公共子序列 + 最长公共子字符串 - 动态规划的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构 - 二叉树 - 面试中常见的二
- 下一篇: 数据结构 - 红黑树