最长公共子序列LCS递归解法

#include<iostream>
#include<string.h>
using namespace std;
int row,col,**map,index,maxLen;
char *record,*lcs;
bool flag=true;
string str1,str2;
/*
	eg: str1="abcb",str2="acb" 

      a b c b
    a 1 0 0 0
	c 0 0 1 0
	b 0 1 0 1    

	map: 如上,以str1长度为row,str2长度为col,当str1[i]==str2[j],map[i][j]=1;
	index:代表record中某时刻的元素个数
	maxLen: 存放dfs过程中,出现的临时最长子序列长度
	record:存放dfs过程中符合条件的CS
	lcs:存放最终的LCS
	flag:控制结果,当str1==str2直接输出,不比dfs 

	思路:先得到map数组,之后从左上至右下开始dfs,每遇到一个1,则跳向下一行的下一列,
	到边界返回并判断得到的CS是否比原来的CS更长. (临时做出来,没有优化算法
	,感觉效率不高,先用着...)
*/

void dfs(int r,int c)//r代表临时的行,c代表临时的列
{
	for(int i=r;i<row;i++)
		for(int j=c;j<col;j++)
			if(map[i][j]==1)
			{
				record[index]=str1[i];
				index++;
				dfs(i+1,j+1);
				index--;
				record[index]=0;
			}
	if(maxLen<index)
	{
		maxLen=index;
		strcpy(lcs,record);
	}
}
void init()
{
	int i,j;
	cin>>str1>>str2;
	if(str1==str2)
	{
		cout<<str1<<endl;
		flag=false;
		return;
	}
	row=str1.length();
	col=str2.length();

	record=new char[row>col?row:col]();
	lcs=new char[row>col?row:col]();
	map=new int*[row];
	index=maxLen=0;

	for(i=0;i<row;i++)
		map[i]=new int[col]();

	for(i=0;i<row;i++)
		for(j=0;j<col;j++)
			if(str1[i]==str2[j])
				map[i][j]=1;
}
void delMem()
{
	for(int i=0;i<row;i++)
		delete[] map[i];
	delete[] map;
}
int main()
{
	init();
	if(flag)
	{
		dfs(0,0);

		cout<<lcs<<endl;

		cout<<maxLen<<endl;

		cout<<strlen(lcs)<<endl;

		delMem();
	}
	return 0;
}

时间: 2024-10-26 12:25:45

最长公共子序列LCS递归解法的相关文章

最长公共子序列 LCS 递归 dp 51Nod 1006

给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列. Input 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000) Output 输出最长的子序列,如果有多个,随意输出1个. Input示例 abcicba abdkscab Output示例 abca 先用dp 找到最大值,且标记路径,然后递归 从终点走到起点,然后输

动态规划算法解最长公共子序列LCS问题

第一部分.什么是动态规划算法 ok,咱们先来了解下什么是动态规划算法. 动态规划一般也只能应用于有最优子结构的问题.最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似).简单地说,问题能够分解成子问题来解决. 动态规划算法分以下4个步骤: 描述最优解的结构 递归定义最优解的值 按自底向上的方式计算最优解的值   //此3步构成动态规划解的基础. 由计算出的结果构造一个最优解.   //此步如果只要求计算最优解的值时,可省略. 好,接下来,咱们

[2016-05-09][51nod][1006 最长公共子序列Lcs]

时间:2016-05-09 21:12:54 星期一 题目编号:[2016-05-09][51nod][1006 最长公共子序列Lcs] 题目大意:[2016-05-09][51nod][1006 最长公共子序列Lcs].md 分析:动态规划 dp[i][j] 表示字符串A以第i个位置 ,字符串B以第j个位置的最长公共子序列的长度 dp[i][j] = dp[i - 1][j - 1] + 1 if a[i] == a[j] else dp[i][j] == max(dp[i - 1][j] ,

1006 最长公共子序列Lcs

1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列. Input 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000) Output 输出最长的子序列,如果有多个,随意输出1个. Input示例 abcicba abdkscab Outpu

POJ 1458 Common Subsequence(最长公共子序列LCS)

POJ1458 Common Subsequence(最长公共子序列LCS) http://poj.org/problem?id=1458 题意: 给你两个字符串, 要你求出两个字符串的最长公共子序列长度. 分析: 本题不用输出子序列,非常easy,直接处理就可以. 首先令dp[i][j]==x表示A串的前i个字符和B串的前j个字符的最长公共子序列长度为x. 初始化: dp全为0. 状态转移: IfA[i]==B[j] then dp[i][j]= dp[i-1][j-1]+1 else dp[

序列最的问题之最长公共子序列LCS

在程序设计竞赛中,我们时常会遇到序列求最值的问题.在讲今天的问题之前,先小小的说明一下,子序列与子串的问题. 子序列:在原序列中不一定连续: 子串:在原序列中必须连续. 接下来,就开始今天要讲的最长公共子序列LCS(Longest Common Subsequence).对于LCS这一类的问题,一般是相对于两个序列而言,str[]与ch[].先假设str的长度为n,ch的长度为m.假设str[]="ASBDAH",ch[]="SDAAH";其中"SDA&q

51nod 1006 最长公共子序列Lcs(dp+string,无标记数组实现)

1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 取消关注 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列. Input 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000) Output 输出最长的子序列,如果有多个,随意输出1个. Input示

求三个字符串的最长公共子序列LCS(A,B,C)

LCS(A,B,C)!=LCS(A,LCS(B,C)) 反例: abcd abcde abced LCS(B,C)求出来可能是abce或者abcd dp[i][j][k]表示A[0...i],B[0...j],C[0...k]的LCS 转移方程: if (a[i]==b[j]&&b[j]==c[k]) dp[i][j][k]=dp[i-1][j-1][k-1]+1; else dp[i][j][k]=max(max(dp[i][j][k], dp[i-1][j][k]), max(dp[i

编程算法 - 最长公共子序列(LCS) 代码(C)

最长公共子序列(LCS) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定两个字符串s,t, 求出这两个字符串最长的公共子序列的长度. 字符串的子序列并一定要连续, 能够包含间隔. 即最长公共子序列问题(LCS, Longest Common Subsequence) 使用动态规划, 假设字符相等, 两个字符串就依次递增一位, 一直到字符串的结尾. 代码: /* * main.cpp * * Created on: 2014.7.17