LCS問題,JAVA實現

本文參照July的博客,第十一章,只給出個人理解和java實現,問題說明略。

1. 窮舉

如果X{1,2,3,4...m}

      y{1,2,3,4,..n}

那麼 x的所有子序列, 2^m  ,  y的所有子序列, 2^n,窮舉的時間複雜度 O(2^(m+n))

2. 果然動態規劃其實才是重點。

   此題的重點在於反證法的使用,但是個人感覺是,除非是自己推出來,否則,總是會忘記。

  反證法和定尾點是解決關鍵。

  目前要求 xm 和 yn的最長公共子序列,那麼定義一個數據結構,xi 和 yj的最長公共子序列  c[i,j]

  然後給出遞歸式子,要麼加1,要麼繼承,

圖片來自 july的文章

這個基本不考數據結構,就考算法

參考 算法給出java代碼

import java.util.Arrays;


public class LCS {
	public static void main(String[] args) {
		char[] X = {'1','A','B','C','B','D','A','B'};
		char[] Y = {'2','B','D','C','A','B','A'};
		
		LCS_LENGTH(X,Y);
		
	}
	
	
	static void LCS_LENGTH(char[] X,char[] Y){
		
		int lenOfX = X.length;
		int lenOfY = Y.length;

		// 存儲記錄長度
		int[][] c = new int[lenOfX][lenOfY];
		// c是由哪一個記錄到達的
		int[][] b = new int[lenOfX][lenOfY];
		
		for(int i=1;i<lenOfX;i++) c[i][0] = 0;
		for(int j=1;j<lenOfY;j++) c[0][j] = 0;
		for(int i=1;i<lenOfX;i++){
			for(int j=1;j<lenOfY;j++){
				if(X[i]==Y[j]){
					c[i][j] = c[i-1][j-1] +1;
					b[i][j] = 1; // "↖"
				}
				else if(c[i-1][j]>=c[i][j-1]){
					c[i][j]= c[i-1][j];
					b[i][j] = 2;// "↑"
				}
				else{
					c[i][j]=c[i][j-1];
					b[i][j]= 3;// "←"
				}
			}
		}
		
//		System.out.println(Arrays.deepToString(b));
		LCS(b,X,lenOfX-1,lenOfY-1);
	}
	
	static void LCS(int[][] b, char[] X,int i , int j){
		if(i==0 || j==0) return;
		if(b[i][j]==1){
			LCS(b,X,i-1,j-1);
			System.out.print(X[i]);
		}
		else if(b[i][j] == 2) LCS(b,X,i-1,j);
		else LCS(b,X,i,j-1);
	}
}

可能是因爲水平低,對此類算法題目無感,既無使用太多的數據結構,也不考驗編程能力,只是抽象,非常抽象,適合數學專業出生的同學,工程師只是負責去實現。


第五節的改進算法確實很精彩,下面詳細看一看。

今天狀態很差,姑且做一次搬運工,劉佳梅女士的解法

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