实验三、最长公共子序列(输出所有最长公共子序列)

这篇博客详细介绍了如何使用动态规划解决寻找两个序列的最长公共子序列问题。作者首先分析了问题的关键性质,然后给出了动态规划方程,并解释了代码实现。博客还包含了程序调试结果和实验体会,强调了递归算法理解的重要性。
摘要由CSDN通过智能技术生成

实验3、最长公共子序列

问题描述与实验目的:

序列Z=<B,C,D,B>是序列X=<A,B,C,B,D,A,B>的子序列,相应的递增下标序列为<2,3,5,7>。

一般地,给定一个序列X=<x1,x2,…,xm>,则另一个序列Z=<z1,z2,…,zk是X的子序列,是指存在一个严格递增的下标序列〈i1,i2,…,ik〉使得对于所有j=1,2,…,k使Z中第j个元素zj与X中第ij个元素相同。

给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。

你的任务是:给定2个序列X、Y,求X和Y的最长公共子序列Z。

输入

输入文件中的第1行是一个正整数T,(0<T<=10),表示有T组测试数据。接下来是每组测试数据的描述,每组测试数据有3行。

测试数据的第1行有2个正整数m、n,中间用一个空格隔开,(0<m,n<50);第2、3行是长度分别为m、n的2个序列X和Y,每个序列的元素间用一个空格隔开。序列中每个元素由字母、数字等构成。

输入直到文件结束。

输出

对输入中的每组测试数据,输出2行。先在一行上输出“Case #”,其中“#”是测试数据的组号(从1开始),再在第2行上输出这2个序列X、Y的最长公共子序列Z的长度及子序列Z(至少一个)。

实验结果:

输入样例

2

7 6

A B C B D A B

  • 9
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,让我来回答您的问题。 最长公共子序列问题是一个经典的计算机科学问题,它的解决方案有很多种。其一种常用的方法是动态规划。 下面是一个 C 语言实现最长公共子序列问题并输出所有最长公共子序列的代码: ```c #include <stdio.h> #include <string.h> #define MAX_LEN 100 int dp[MAX_LEN][MAX_LEN]; void print_all_lcs(char str1[MAX_LEN], char str2[MAX_LEN], char lcs[MAX_LEN], int lcs_len, int i, int j) { if (i == 0 || j == 0) { for (int k = lcs_len - 1; k >= 0; k--) { printf("%c", lcs[k]); } printf("\n"); return; } if (str1[i - 1] == str2[j - 1]) { lcs[lcs_len] = str1[i - 1]; print_all_lcs(str1, str2, lcs, lcs_len + 1, i - 1, j - 1); } else { if (dp[i - 1][j] >= dp[i][j - 1]) { print_all_lcs(str1, str2, lcs, lcs_len, i - 1, j); } if (dp[i][j - 1] >= dp[i - 1][j]) { print_all_lcs(str1, str2, lcs, lcs_len, i, j - 1); } } } void lcs(char *str1, char *str2) { int len1 = strlen(str1); int len2 = strlen(str2); memset(dp, 0, sizeof(dp)); for (int i = 1; i <= len1; i++) { for (int j = 1; j <= len2; j++) { if (str1[i - 1] == str2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; } else { dp[i][j] = (dp[i - 1][j] > dp[i][j - 1]) ? dp[i - 1][j] : dp[i][j - 1]; } } } char lcs[MAX_LEN]; print_all_lcs(str1, str2, lcs, 0, len1, len2); } int main() { char str1[MAX_LEN]; char str2[MAX_LEN]; scanf("%s%s", str1, str2); lcs(str1, str2); return 0; } ``` 这个代码可以输出任意两个字符串的最长公共子序列以及所有的最长公共子序列
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值