动态规划-最长公共子序列(LCS)

本文介绍了一种求解最长公共子序列问题的动态规划算法,通过具体实例展示如何找到两个字符串的最长公共子序列,并提供了完整的Java代码实现。

最长公共子序列问题是求两个序列的一个最长的公共的子序列,不一定是连续的,但是顺序必须是正确的。

S1:  b e a u t y w q l o v e

S2: w e i q i n g b e a l o v e

那么他们的最长公共子序列为bealove,长度为7(测试用例)

c表用来记录最长子序列的长度,如图所示。



/**
 * 最长公共子序列的动态规划算法O(mn)
 * @author Qing
 *
 */
public class LCS {
	public static final int N = 15;
	public static final int M = 12;
	public static String[] s1 = {"w","e","i","q","i","n","g","b","e","a","u","l","o","v","e"};
	public static String[] s2 = {"b","e","a","u","t","y","w","q","l","o","v","e"};
	public static int[][] c = new int[N+1][M+1];
	
	public static void findLCS(){
		for(int i = 1; i <= N; i++){
			for(int j = 1; j <= M; j++){
				//当两个字符相匹配,则最长序列数目加一
				if(s1[i-1] == s2[j-1]){
					c[i][j] = c[i - 1][j - 1] + 1;
				}
				//如果两个字符不匹配,则最长序列为相邻序列中最长的那个
				else if(c[i - 1][j] < c[i][j - 1]){
					c[i][j] = c[i][j - 1];
				}
				else{
					c[i][j] = c[i - 1][j];
				}
			}
		}
	}
	//输出c表
	public static void print(int[][] a){
		int length = a.length;
		int width = a[0].length;
		System.out.println("length: " + length +", width: " + width);
		System.out.print("/ /");
		for(int k = 0; k < width - 1; k++){
			System.out.print(" " + s2[k]);
		}
		System.out.println(" ");
		for(int i = 0; i < length; i ++){
			if(i > 0){
				System.out.print(s1[i-1] + " ");
			}
			else{
				System.out.print("/ ");
			}
			for(int j = 0; j < width; j ++){
				System.out.print(a[i][j]+" ");
			}
			System.out.println(" ");
		}
	}
	public static void main(String[] args){
		findLCS();
		print(c);
	}

}


运行结果如下:


本算法及其实现参考算法之道第二版第四章动态规划

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值