用动态规划实现最长公共子序列C语言

数据结构与算法 专栏收录该内容
39 篇文章 0 订阅

思路:
有两个字符数组a,b
分为三种情况:
比较a,b数组当前长度的最后一个字符

  1. 相等时, lsc值等于前一段值加1
    即:当a[i-1]==b[j-1]时(因为i,j是从1开始,所以是a[i-1],b[j-1]),lsc[i][j]=lsc[i-1][j-1]+1
  2. 不相等,把a数组的最后一个字符去掉的最长公共子序列大于把b数组的最后一个字符去掉的最长公共子序列
    即:当lsc[i-1][j]>=lsc[i][j-1]时,lsc[i][j]=lsc[i-1][j]
  3. 不相等,把b数组的最后一个字符去掉的最长公共子序列大于把a数组的最后一个字符去掉的最长公共子序列
    即:当lsc[i-1][j]<lsc[i][j-1]时,lsc[i][j]=lsc[i][j-1]

代码:

#include <stdio.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void LSCLength(char a[],char b[],int c[11][10],int lsc[11][10],int la,int lb)
{
	for(int i=0;i<=la;i++)	lsc[0][i]=0;
	for(int i=0;i<=lb;i++)	lsc[i][0]=0;
	for(int i=1;i<=la;i++)
	{
		for(int j=1;j<=lb;j++){
			if(a[i-1]==b[j-1])
			{
				lsc[i][j]=lsc[i-1][j-1]+1;
				c[i][j]=1;
			}
			else if(lsc[i-1][j]>=lsc[i][j-1])
			{
				lsc[i][j]=lsc[i-1][j];
				c[i][j]=2;
			}
			else{
				lsc[i][j]=lsc[i][j-1];
				c[i][j]=3;
			}
		}
	}

	
}
void LSC(int i,int j,char a[],int c[11][10]) 
{
	if(i==0 || j==0)	return;
	if(c[i][j]==1)
	{
		LSC(i-1,j-1,a,c);
		printf("%3c  ",a[i-1]);
	}
	else if(c[i][j]==2)
	{
		LSC(i-1,j,a,c);
	}
	else
	{
		LSC(i,j-1,a,c);
	}
	
}
int main(int argc, char** argv) {
	char a[10]={'d','i','d','a','c','t','i','c','a','l'};
	char b[9]={'a','d','v','a','n','t','a','g','e'};
	int c[11][10]={0};
	int lsc[11][10]={0};
	LSCLength(a,b,c,lsc,10,9);
	for(int i=0;i<=10;i++)
	{
		for(int j=0;j<=9;j++)
		{
			printf("%d  ",lsc[i][j]);
		}
		printf("\n");
	}
	printf("长度:%d\n比较情况\n",lsc[10][9]);
	
	for(int i = 0;i<11;i++){
		for(int j = 0;j<10;j++){
			printf("%3d",c[i][j]);
		}
		printf("\n");
	}
	LSC(10,9,a,c);
	return 0;
} 

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 0
    评论
  • 10
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值