最长公共子序列的动态规划求解

从一个看来的题目想起来的,说,有一个无序字符串,如何挑出最少的元素,让余下的部分变成一个有序串。

没想到方法,给的答案是:将字符串排序,找出排序后的字符串和原字符串的最长公共子序列,

因为子序列是不要求连续的,所以不能用最长公共子串的算法,

思路:

建立一个矩阵,从后往前推,如果 a[i] == b[j],那么最长公共子序列肯定要包含这一格;否则的话,最长公共子序列就是 max{a[i-1],  b[j-1]},

代码:

#include <iostream>
using namespace std;

void func(char* s1, char *s2){
	int l1 = strlen(s1), l2 = strlen(s2);
	int arr[l1+1][l2+1];
	//第一行和第一列都用来放 0 , 
	memset(arr, 0, sizeof(arr));
	int m =0, n = 0;
	for(int m = 0; m < l1; ++m){
		for(int n = 0; n < l2; ++n){
			if(s1[m] == s2[n])
				arr[m+1][n+1] = arr[m][n] +1;
			else
				arr[m+1][n+1] = (arr[m][n+1]>arr[m+1][n])? arr[m][n+1] : arr[m+1][n];
		}
	}//建立矩阵 
	for(m = 0; m <= l1; ++m){
		for(n = 0; n <= l2; ++n){
			cout << arr[m][n] << "  ";
		}
		cout << endl;
	}//输出矩阵,看的直观点,
	m = l1, n = l2;
	while(arr[m][n] != 0){
		if( (arr[m][n] = arr[m-1][n-1] +1) && (arr[m][n-1] == arr[m-1][n] ) && (arr[m][n-1] == arr[m-1][n-1])){
			//条件判别,如果在矩阵中,这个值的上,左,左上都比它小,那么这个店肯定是个相同的点,
			//所以就输出这个值,然后向左上走一格 
			cout << s1[m-1];
			m = m-1, n = n-1;
		}
		else{
			if(arr[m][n-1] == arr[m][n])
				m = m, n = n-1;
			else
				n = n, m = m-1;
			//此处之所以要判断,只要是为了应付边界情况下, 防止出界
		}
	}//输出的是逆序的,暂时不care 
	cout << endl;
}

int main(){
	char s1[] = "ABCBDAB", s2[] = "BDCABA";
	func(s1, s2);
    system("pause");
    return 0;
}

windows下dev cpp通过,如果放到 Linux 下肯定一堆报错,各种没包含,就这样吧,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值