代码改变世界

js动态规划---最长子序列(lcs)

2018-07-17 13:43  muamaker  阅读(1574)  评论(0编辑  收藏  举报
		function LCS(wordX, wordY) {
			var m = wordX.length;
			var n = wordY.length;
			this.lcs = function(){
				var l = [];
				var path = [];
				var i, j, a, b;
				for(i = 0; i <= m; ++i) {
					l[i] = [];
					path[i] = [];
					for(j = 0; j <= n; j++) {
						l[i][j] = 0;
						path[i][j] = 0;
					}
				}
	
				for(i = 1; i <= m; i++) {
					for(j = 1; j <= n; j++) {
						if(wordX[i - 1] == wordY[j - 1]) {
							l[i][j] = l[i - 1][j - 1] + 1;
							path[i][j]  = 1; //取左上角
						} else {
							a = l[i - 1][j]; //取上边
							b = l[i][j - 1];  //取左边
							if(b >= a){
								l[i][j] = b;
								path[i][j] = 2; 
							}else{
								l[i][j] = a;
								path[i][j] = 3;
							}
						}
					}
				}
				return {
					l:l,
					p:path,
					len:l[m][n]
				};
			}
			
			this.getPath = function(){
				var obj = this.lcs();
				var p = obj.p;
				var l = obj.l;
				var list = [];
				print(m,n,list);
				
				function print(i,j,list){
					var typ = p[i][j];
					
					if(i==0 || j==0){
						return ;
					}
					
					console.log(i,j,typ,wordX[i-1],wordY[j-1])
					if(typ == 1){
						print(i-1,j-1,list);
						list.push(wordX[i-1]); //为1时,表示 wordx[i-1]=wordy[j-1],任意取一个
					}
					if(typ == 2){
						print(i,j-1,list);
					}
					
					if(typ == 3){
						print(i-1,j,list);
					}
				}
				
				return list;
				
			}

		}
		
		var lcs = new LCS('ABCADAB', 'BACDBA');
		console.log(lcs.lcs());
		console.log(lcs.getPath());
		//B A D B
		
		//l[i][j] 表示 stri , strj 最大公共子序列
		//如果 str1[i] == str2[j], 则 l[i][j] = l[i-1][j-1] + 1;
		//如果 str1[i] != str2[j],则 l[i][j] = max(l[i-1][j],l[i][j-1]) ;