夜深人静写算法——最长公共子序列(动态规划)

一. 问题描述

给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence)。比如字符串1:BDCABA;字符串2:ABCBDAB

则这两个字符串的最长公共子序列长度为4,最长公共子序列是:BCBA

二.寻找最优子结构,

用dp[i][j] 来表示第一个字符串前 i 个字符和第二个字符串前 j 个字符的最优解(最长公共子序列);

有两种可能: (字符数组 s1[n] 和字符数组 s2[n] )

 1 .   s1[i] == s2[j] , dp[i][j] = dp[i-1][j- ]+1  : 如果s1[i] == s2[j]  那么说明dp[i][j] 的最优解是dp[i-1][j-1]的最优解加一;

 2 .   s1[i] != s2[j]  , 如果  dp[i][j-1] > dp[i-1][j]  ,那么dp[i][j] = dp[i][j-1] ; 如果dp[i-1][j] > d[i][j-1] ,那么dp[i][j] = dp[i-1][j];

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAX 10
using namespace std;

int MaxL(string &str1,string &str2,int BT[MAX][MAX]){
	size_t size1 = str1.size();      //字符串str1的长度
	size_t size2 = str2.size();      //字符串str2的长度
	int **dp;
	 dp = new int*[size1];
	for(int i = 0; i < size1 ;i++)
	 	dp[i] = new int[size2];
	 	
	for(int i = 0; i < size1;i++)
		dp[i][0] = 0;                  //如果str1的长度为0,最长公共子序列为0
	for(int i = 0;i < size2;i++)
		dp[0][i] = 0;                  //如果str2的长度为0,最长公共子序列为0
	for(int i = 1; i < size1;i++)
		for(int j = 1; j < size2;j++){
			if(str1[j] == str2[i]){   //如果相等
				dp[i][j] = dp[i-1][j-1] + 1; BT[i][j] = 1; //BT数组用来记录对于字符串的操作,用来寻找最优子序列
			}else if(dp[i-1][j] > dp[i][j-1]){     
				dp[i][j] = dp[i -1][j] ;     BT[i][j] = 2;
			}else{
				dp[i][j] = dp[i][j -1] ;    BT[i][j] = 3;
			}
		}
} 

void Traceback(int i,int j,int BT[MAX][MAX],string &x){ //通过记录
	if(i == 0 || j== 0)
		return;
	else{
		if(BT[i][j] == 1){            //操作1:如果str1的前i个字符和str2的前j个字符的最优解进行的操作是 1 的话,就输出str1[i],然后在追溯到str1的前i-1个字符和str2的前j-1个字符的最优解
			Traceback(i-1,j-1,BT,x);cout<<x[i];
		}else if(BT[i][j] == 2)  
			Traceback(i-1,j,BT,x);   //操作2:最优解进行的操作是2,不输出,直接追溯到str1的i-1个字符和str2的j个字符的最优解
		 else 
			Traceback(i,j-1,BT,x);   //操作3:最优解进行的操作是2,不输出,直接追溯到str1的i个字符和str2的j-1个字符的最优解
	}
}

int main(){
 	string A = "ABCDEFGHTI";
	string B = "BCDAEFHGIT";
	int BT[10][10];
	MaxL(A,B,BT);
	cout<<"最长公共子序列为:"; 
	Traceback(10,10,BT,A);
}

猜你喜欢

转载自blog.csdn.net/curtern/article/details/83957710
今日推荐