動態規劃-最長公共自序列(java)
阿新 • • 發佈:2019-01-10
package com.wanali.dynamic_planning; /** * 最長公共自序列LCS(動態規劃求解) * @author wan_ys * * 2019年1月10日上午8:43:34 */ public class LCS { public static void main(String[] args) { String[] x = new String[] { "A", "B", "C", "B", "D", "A", "B" }; String[] y = new String[] { "B", "D", "C", "A", "B", "A" }; getLCSLength(x, y); } /** * 計算LCS的長度 * @param x * @param y */ static void getLCSLength(String[] x, String[] y) { int m = x.length + 1; int n = y.length + 1; int[][] b = new int[m][n];//定義LCS長度陣列 String[][] c = new String[m][n]; //記錄回溯方向,方便找公共子序列 //初始化第一列為0 for (int i = 0; i < m; i++) { b[i][0] = 0; } //初始化第一行為0 for (int j = 0; j < n; j++) { b[0][j] = 0; } /*從(1,1)開始往後比較x[i]==y[j],b[i][j]=c[i-1][j-1]+1; * b[i-1][j]>=b[i][j-1],則該位置的箭頭向上指 * b[i][j-1]>b[i-1][j],則該位置的箭頭向左指 */ for (int i = 1; i < m; i++) { for (int j = 1; j < n; j++) { //注意這裡應該是x[i-1]和y[j-1] if (x[i - 1] == y[j - 1]) { b[i][j] = b[i - 1][j - 1] + 1; c[i][j] = "upleft"; } else if (b[i - 1][j] >= b[i][j - 1]) {//上邊位置大於等於左邊位置 b[i][j] = b[i - 1][j]; c[i][j] = "up"; } else {//左邊位置大於上邊位置 b[i][j] = b[i][j - 1]; c[i][j] = "left"; } } } //列印公共子序列的長度 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { System.out.print(b[i][j] + "\t"); } System.out.println(); } //列印回溯方向 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { System.out.print(c[i][j] + "\t"); } System.out.println(); } System.out.println("一個最長公共自序列為:"); //注意這裡是m-1,n-1 getLCS(c, x, m-1, n-1); } static void getLCS(String[][] c, String[] x, int i, int j) { if (i == 0 || j == 0) { return; } if (c[i][j] == "upleft") { getLCS(c, x, i - 1, j - 1); System.out.print(x[i - 1]); } else if (c[i][j] == "up") { getLCS(c, x, i - 1, j); } else { getLCS(c, x, i, j - 1); } } }