计算回文子序列(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;
	}
}


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