Longest common subsequence problem and poj 1159 Palindrome

16 篇文章 0 订阅
11 篇文章 0 订阅

 The longest common subsequence problem is a very basic problem in dynamic programming. If you dive in,there is manyothermethods to compute thelongest common subsequence. Hereis just the very basic methods,it also hassome relationship withpalindrome problem. To make a string become palindrome,itcan compute the long common subsquence first.


Java code:

package datastructure.test;

public class LCS {
	private String X;
	private String Y;
	private int M;	// the length of X
	private int N;	// the length of Y
	private int[][] opt;	// two dimensional array to store the maximum length of X and Y
	
	/*
	 * constructor
	 */
	public LCS(String X, String Y) {
		this.X = X;
		this.Y = Y;
		this.M = X.length();
		this.N = Y.length();
		
		// opt[i][j] = length of LCS of x[i..M] and y[j..N]
		this.opt = new int[M + 1][N + 1];
	}
	
	/*
	 * compute the LCS and all subproblem via dynamic programming
	 * the longest length be set in opt[0][0]
	 */
	public void dyncomputeLCS() {
		for (int i = M - 1; i >= 0; i--) {
			for (int j = N - 1; j >= 0; j--) {
				if (this.X.charAt(i) == this.Y.charAt(j)) {
					this.opt[i][j] = this.opt[i + 1][j + 1] + 1;
				}
				else {
					this.opt[i][j] = Math.max(this.opt[i + 1][j], this.opt[i][j + 1]);
				}
			}
		}
	}
	
	/*
	 * compute the LCS of X and Y with the recursive way
	 */
	public int reclcs (String X, String Y) {
		if (X.length() == 0 || Y.length() == 0) {
			return 0;
		}
		else if (X.charAt(X.length() - 1) == Y.charAt(Y.length() - 1)) {
			return reclcs(X.substring(0, X.length() - 1), Y.substring(0, Y.length() - 1)) + 1;
		}
		else {
			return Math.max(reclcs(X.substring(0, X.length() - 1), Y), reclcs(X, Y.substring(0, Y.length() - 1)));
		}
	}
	
	/*
	 * compute the LCS of X and Y with the dynamic way
	 */
	public int dynlcs (String X, String Y) {
		int i, j;
		int lenx = X.length();
		int leny = Y.length();
		int[][] table = new int[lenx][leny];
		
		/*
		 * below init segment can be ignored, because java will do it by default
		for (i = 1; i < lenx; i++) {
			table[i][0] = 0;
		}
		
		for (j = 1; j < leny; j++) {
			table[0][j] = 0;
		}
		*/
		
		for (i = 1; i < lenx; i++) {
			for (j =1; j < leny; j++) {
				if (X.charAt(i) == Y.charAt(j)) {
					table[i][j] = table[i - 1][j - 1] + 1;
				}
				else {
					table[i][j] = Math.max(table[i - 1][j], table[i][j -1]);
				}
			}
		}
		
		return table[lenx - 1][leny - 1];
	}
	
	/*
	 * with dynamic way to compute the shortest length of insert characters to 
	 * make X to be palindrome
	 */
	public int palindromedyn (String X) {
		int lenx = X.length();
		int[][] dp = new int[lenx][lenx];
		
		for (int i = lenx - 1; i >= 0; i--) {
			for (int j = i + 1; j <= lenx - 1; j++) {
				if (X.charAt(i) == X.charAt(j)) {
					dp[i][j] = dp[i + 1][j - 1];
				}
				else {
					dp[i][j] = Math.min(dp[i + 1][j], dp[i][j - 1]) + 1;
				}
			}
		}
		
		return dp[0][X.length() - 1];
	}
	
	/*
	 * use dynamic way to compute the shortest length of insert characters to make X's substring 
	 * to be palindrome, the substring's index is from start to end
	 * 
	 */
	public int palindromedyn (String X, int start, int end) {
		int lenx = X.length();
		
		assert(start >= 0 && start < lenx && end >= 0 && end < lenx && start < end);
		
		int[][] dp = new int[lenx][lenx];
		
		for (int i = end - 1; i >= start; i--) {
			for (int j = i + 1; j <= end - 1; j++) {
				if (X.charAt(i) == X.charAt(j)) {
					dp[i][j] = dp[i + 1][j - 1];
				}
				else {
					dp[i][j] = Math.min(dp[i + 1][j], dp[i][j - 1]) + 1;
				}
			}
		}
		
		return dp[start][end - 1];
	}
	
	/*
	 * with recursive way to compute the shortest length of insert characters to 
	 * make X to be palindrome
	 */
	public int palindromerec (String X) { 
		if (X.length() == 0 || X.length() == 1) {
			return 0;
		}
		else if (X.charAt(0) == X.charAt(X.length() - 1)){
			return palindromerec(X.substring(1, X.length() - 1));
		}
		else 
		{
			int a = palindromerec(X.substring(0, X.length() - 1));
			int b = palindromerec(X.substring(1, X.length()));
			return Math.min(a, b) + 1;
		}
	}
	
	/*
	 * use recursive way to compute the shortest length of insert characters to make X's substring 
	 * to be palindrome, the substring's index is from start to end
	 * 
	 */
	public int palindromerec (String X, int start, int end) {
		assert(start >= 0 && start < X.length() && end >= 0 && end < X.length());
		
		if (X.length() == 0 || X.length() == 1 || start >= end) {
			return 0;
		}
		else if (X.charAt(start) == X.charAt(end - 1)){
			return palindromerec(X.substring(start + 1, end - 1));
		}
		else {
			int a = palindromerec(X.substring(start, end - 1));
			int b = palindromerec(X.substring(start + 1, end));
			return Math.min(a, b) + 1;
		}
	}
	
	/*
	 * compute the shortest length of make X to a palindrome with longest common subsequence
	 */
	public int palindromelcs (String X) {
		String Y = stringreverse(X);
		//int lcslen = reclcs(X, Y);
		int lcslen = dynlcs(X, Y);
		return X.length() - lcslen;
	}
	
	/*
	 * compute the shortest length of make X's substring to a palindrome with longest common subsequence
	 * the index is from start to end
	 */
	public int palindromelcs (String X, int start, int end) {
		String Y = stringreverse(X.substring(start, end));
		int lcslen = reclcs(X.substring(start, end), Y);
		//int lcslen = dynlcs(X.substring(start, end), Y);
		return end - start - lcslen;
	}
	
	/*
	 * get the string s's reversed string 
	 */
	private String stringreverse (String s) {
		String t = "";
		
		for (int i = s.length() - 1; i >= 0; i--) {
			t = t + s.charAt(i);
		}
		return t;
	}
	
	/*
	 * get the longest common substring length of X and Y
	 */
	public int maxLength () {
		return this.opt[0][0];
	}
	
	private int maxtriple (int a, int b, int c) {
		int max;
		
		if (a > b) 
			max = a;
		else
			max = b;
		
		if (max < c)
			max = c;
		
		return max;
	}
	
	private int mintriple (int a, int b, int c) {
		return Math.min(a, Math.min(b, c));
	}
	
	/*
	 * print the longest common substring of X and Y
	 */
	public void printLCS() {
		int i = 0, j = 0;
		
		while (i < this.M && j < this.N) {
			if (this.X.charAt(i) == this.Y.charAt(j)) {
				System.out.print(this.X.charAt(i));
				i++;
				j++;
			}
			else if (this.opt[i + 1][j] >= this.opt[i][j + 1]) {
				i++;
			} 
			else {
				j++;
			}
		}
	}
	
	

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String X = "afddddd";
		String Y = "eindddd";
		
		LCS lcs = new LCS(X, Y);
		//lcs.dyncomputeLCS();
		//System.out.println("the max length of X and Y is : " + lcs.maxLength());
		//System.out.println("the max length of X and Y is : " + lcs.dynlcs(X, Y));
		//System.out.println("the recursive max length of X and Y is : " + lcs.reclcs(X, Y));
		
		//System.out.println("The reversed string is : " + lcs.stringreverse("abcd"));
		
		//lcs.printLCS();

		// compute poj 1159 Palindrome
		//System.out.println("The palindrome length is : " + lcs.palindromedyn("Ab3bd"));
		System.out.println("The palindrome dynamic length is : " + lcs.palindromedyn("Ab3bd", 0, 5));
		//System.out.println("The palindrome recursive length is : " + lcs.palindromerec("Ab3bd", 0, 5));
		//System.out.println("The palindrome lcs length is : " + lcs.palindromelcs("Ab3bd", 0, 5));
		
	}

}

Python code:

D = {}

def lcs_recursive(X, Y):
    x , y = len(X), len(Y)
    global D
    
    if x == 0 or y == 0:
        return 0
    elif X[x - 1] == Y[y - 1]:
        if x - 1 not in D:
            D[x - 1] = X[x - 1]
        return lcs_recursive(X[: x - 1], Y[: y - 1]) + 1
    else:
        return max(lcs_recursive(X, Y[: y - 1]), lcs_recursive(X[: x - 1], Y))
    
def lcs_dynamic(X, Y):
    m , n = len(X), len(Y)
    c = [[0 for col in range(m + 1)] for row in range(n + 1)]
    
    for i in range(m):
        c[i][0] = 0
    for j in range(n):
        c[0][j] = 0
    
    for i in range(m):
        for j in range(n):
            if X[i] == Y[j]:
                c[i + 1][j + 1] = c[i][j] + 1
            elif c[i][j + 1] >= c[i + 1][j]:
                c[i + 1][j + 1] = c[i][j + 1]
            else:
                c[i + 1][j + 1] = c[i + 1][j]
    
    return c[m][n]

def lcs_dynamic1(X, Y):
    m , n = len(X), len(Y)
    tuple = (0, False)
    c = [[tuple for col in range(m + 1)] for row in range(n + 1)]
    
#    for i in range(m):
#        c[i][0] = 0
#    for j in range(n):
#        c[0][j] = 0
    
    for i in range(m):
        for j in range(n):
            if X[i] == Y[j]:
                c[i + 1][j + 1] = (c[i][j][0] + 1, True)
            elif int(c[i][j + 1][0]) >= int(c[i + 1][j][0]):
                c[i + 1][j + 1] = (c[i][j + 1][0], False)
            else:
                c[i + 1][j + 1] = (c[i + 1][j][0], False)
    
    return c

def print_lcs(C, m, n, X):
    for i in range(m):
        for j in range(n):
            if C[i][j][1] == True:
                print(X[i - 1])
    

def test():
    X = "abcddd"
    Y = "bcddde"
    lcs_len = lcs_recursive(X, Y)
    print(lcs_len)
    print(D.keys(), D.values())
    
def test1():
    X = "abcddd"
    Y = "bcddde"
    lcs= lcs_dynamic1(X, Y)
    print_lcs(lcs, len(X), len(Y), X)
    #print(lcs_len, len(lcs_len))

if __name__ == "__main__":
    test1()
#    tuple = (0, False)
#    multilist = [[tuple for col in range(5)] for row in range(3)] 
#    multilist[0][4] = (5, True)
#    h = multilist[0][4][0]
#    print(int(h) > 4)
    #test()
#    X = "abcd"
#    x = len(X)
#    print(X[x - 1])





 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值