求最长公共子序列

根据前边转载他人的文章,自己写了一遍:

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

void lcs(char *a, char *b, int m, int n, int **c, int **s)
{
	if (m == 0 || n == 0 || a == NULL || b == NULL )
	{
		return;
	}
	int i,j;
	for (i = 0; i <= m; i++)
	{
		c[i][0] = 0;
	}
	for (j = 1; j <= n; j++)
	{
		c[0][j] = 0;
	}
	for (i = 1; i <= m; i++)
	{
		for (j = 1; j <= n; j++)
		{
			if (a[i-1] == b[j-1])//注意
			{
				c[i][j] = c[i-1][j-1] + 1;//c[i][j]对应的是a[0到i-1]与b[0到j-1]的公共子序列
				s[i][j] = 0;
			}
			else
				if (c[i-1][j] > c[i][j-1])
				{
					c[i][j] = c[i-1][j];
					s[i][j] = 1;
				}
				else
				{
					c[i][j] = c[i][j-1];
					s[i][j] = -1;
				}
		}
	}
}

void printlcs(char *a, int line, int row, int **c, int **s)
{
	//if (line == 0 || row == 0)
	//{
	//	return;
	//}
	if (c[line][row] == 0)//为什么加这个
	{
		return;
	}
	int i = line, j = row;
	if (s[i][j] == 0)
	{
		cout << a[i - 1] << ' ';//为什么不是输出a[i]
		printlcs(a, i - 1, j - 1, c, s);
	}
	else
		if (s[i][j] == 1)
		{
			printlcs(a, i - 1, j, c, s);
		}
		else
			printlcs(a, i, j - 1, c ,s);
}
int _tmain(int argc, _TCHAR* argv[])
{
	char a[] = "abcbdab";
	char b[] = "bdcaba";
	int length1 = sizeof(a)/sizeof(a[0]);
	int length2 = sizeof(b)/sizeof(b[0]);
	int **c = new int*[length1];
	int **s = new int*[length1];
	for (int i = 0; i < length1; i++)
	{
		c[i] = new int[length2];
		s[i] = new int[length2];
	}
	lcs(a, b, length1 - 1, length2 - 1, c, s);
	cout << c[length1 - 1][length2 - 1];
	printlcs(a, length1 - 1, length2 - 1, c, s);
	system("pause");
	return 0;
}

红色部分的代码也可改为如下:

<strong><span style="font-size:18px;">void printlcs(char *a, int line, int row,  int **s)
{
        if (line == 0 || row == 0)
	{
		return;
	}
	int i = line, j = row;
	if (s[i][j] == 0)
	{
		cout << a[i - 1] << ' ';//注意
		printlcs(a, i - 1, j - 1, s);
	}
	else
		if (s[i][j] == 1)
		{
			printlcs(a, i - 1, j, s);
		}
		else
			printlcs(a, i, j - 1, s);
}
这两个不同的控制条件都是为了防止在行或者列等于零的情况下,还在访问s二维数组而引起冲突。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值