計算迴文子序列(Java語言,動態規劃,遞歸)

LCS是指最長公共子序列。計算2個字符串的LCS的算法,被廣泛應用於搜索引擎,文本編輯器,文本比較工具,IDE等工具中。

LCS計算基於已經證明的一種遞推關係。即:

1.當Xm == Yn時,LCS(X(m),Y(n)) = LCS(X(m-1),Y(n-1)) + Xm

2.當Xm != Yn時,LCS(X(m),Y(n)) = max( LCS(X(m-1),Y(n)), LCS(X(m),Y(n-1))


基於以上遞推關係則可以推導出LCS算法的基本要領:

1.基於遞推關係計算出LCS的長度矩陣和方向矩陣.

2.基於方向矩陣則可計算任意的X(m)序列和Y(n)序列的LCS。


什麼是方向矩陣?

簡言之,方向矩陣記錄了給定的m與n,LCS(X(m),Y(n))的計算方法。有了這個矩陣,我們就知道,LCS(X(m),Y(n))是應該轉化成上述推導式中的哪一種情況。顯然,方向矩陣共有3種方向。


import java.io.*;
class test
{
	public static void main (String[] args) throws java.lang.Exception
	{
	    char x[] = "abcdefaacff".toCharArray();
	    char y[] = "abdfeaacaa".toCharArray();
		getStringsLCS(x,y);
	}
	
	public static int getStringsLCS(char []x, char[] y) {
	    int m = x.length;
	    int n = y.length;
	    int [][] c = new int[m + 1][n + 1];
	    int [][] b = new int[m + 1][n + 1];
	    
	    for(int i = 0;i <= m; i++) {
	        c[i][0] = 0;
	    }
	    for(int i = 0;i <= n; i++) {
	        c[0][i] = 0;
	    }
	    
	    for(int i = 0;i < m; i++) {
	        for(int j = 0;j < n; j++) {
	            if(x[i] == y[j]) {
	                c[i + 1][j + 1] = c[i][j] + 1;
	                b[i + 1][j + 1] = 0;
	            }
	            else if(c[i + 1][j] >= c[i][j + 1]) {
	                c[i + 1][j + 1] = c[i + 1][j];
	                b[i + 1][j + 1] = 1;
	            }
	            else {
	                c[i + 1][j + 1] = c[i][j + 1];
	                b[i + 1][j + 1] = 2;
	            }
	        }
	    }
	    
	    //printArray2D(b);
	    
	    StringBuilder sb = outputStringsLCS(b,x,m,n);
	    System.out.print(sb);
	    
	    return 0;
	}
	
	static void printArray2D(int[][] c) {
	    for(int i = 0;i < c.length;i ++) {
	        for(int j = 0;j < c[0].length;j ++) {
	            System.out.print(c[i][j]);
	        }
	        System.out.println("");
	    }
	}
	
	static StringBuilder outputStringsLCS(int[][] b,char[] x, int i, int j) {
	    if(i == 0 || j == 0) {
	        return new StringBuilder();
	    }
	    
	    StringBuilder sb;
	    
	    if(b[i][j] == 0) {
	        sb = outputStringsLCS(b, x, i - 1, j - 1);
	        sb.append(x[i - 1]);
	    }
	    else if(b[i][j] == 1) {
	        return outputStringsLCS(b, x, i, j - 1);
	    }
	    else {
	        return outputStringsLCS(b, x, i - 1, j);
	    }
	    return sb;
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章