最长公共子序列

234567

23867

resu:7632


以下代码是看《算法设计与分析》之后,随便写写试试看对不对的。。。

请童鞋们去看书认真学习。。


code

#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
using namespace std;

#define LEN 10

#define  elemType  char

/*分治法求解最长公共子序列
分治法就是用一张表记录一个大问题的子问题的解,
这样就可以再计算大问题时避免重复计算了。。
下面用 c[i][j] 来记录子问题 x[i] y[j]的 最长公共序列的长度。
	用 b[i][j] 来记录  c[i][j] 是通过哪个子问题得到的解, 其中c[i][j]可由3个子问题中的一种求得.
	递归方式给出c[i][j]的求取方法:
	c[i][j] = 1 + c[i - 1][j - 1];  if( x[i] == y[j]  && i > 0 && j > 0 )   b[i][j] = 0
	c[i][j] = max{ c[i][j - 1], c[i - 1][j]};   if( x[i] != y[j] && i > 0 && j > 0 )   c[i][j - 1] ==> b[i][j] = 1  c[i - 1][j]==>b[i][j] = 2
	c[i][j] = 0;  if(i == 0 || j  == 0)
*/
void LCSlength(elemType x[], elemType y[], int lenX, int lenY, int c[LEN][LEN], int b[LEN][LEN])
{
	//x[i]和 y[0]的公共子序列长度为0
	for(int i = 0; i <= lenX; i++)
		c[i][0] = 0;

	//y[i]和 x[0]的公共子序列长度为0
	for(int i = 0; i <= lenY; i++)
		c[0][i] = 0;

	for(int i = 1; i <= lenX; i++)
	{
		for(int j = 1; j <= lenX; j++)
		{
			if(x[i - 1] == y[j - 1]) //x y 元素从0开始编号,其结果存放在从1开始编号的c哩。。
			{
				c[i][j] = 1 + c[i - 1][j - 1];
				b[i][j] = 0;
			}
			else if(c[i][j - 1] > c[i - 1][j])
			{
				c[i][j] = c[i][j - 1];
				b[i][j] = 1;
			}
			else
			{
				c[i][j] = c[i - 1][j];
				b[i][j] = 2;
			}
		}//end-for-j
	}//end-for-i

}

void printLCS(elemType x[], int lenX, int lenY, int b[][LEN])
{
	if(lenX == 0 || lenY == 0)
		return;

	if(b[lenX][lenY] == 0)
	{
		cout<<x[lenX - 1]<<" ";
		printLCS(x, lenX - 1, lenX - 1, b);
	}
	else if(b[lenX][lenY] == 1)
		printLCS(x, lenX, lenY - 1, b);
	else
		printLCS(x, lenX - 1, lenY, b);

}

void main()
{
	elemType x[LEN] = {"1234567"};
	elemType y[LEN] = {"23867"};

	int c[LEN][LEN];
	int b[LEN][LEN];

	int lenX = strlen(x);
	int lenY = strlen(y);

	LCSlength(x, y, lenX, lenY, c, b);
	
	printLCS(x, lenX, lenY, b);

	system("pause");
}


LCSlength中,下面,从1开始编号。。。因为c 的第0行和第0列要有初始值
for(int i = 1; i <= lenX; i++)
	{
		for(int j = 1; j <= lenX; j++)
		{

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值