1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 动态规划 dp03 最长公共子串问题 c代码

动态规划 dp03 最长公共子串问题 c代码

时间:2021-02-11 23:28:57

相关推荐

动态规划 dp03 最长公共子串问题 c代码

题目:

若序列Z是序列X的子序列,又是Y的子序列,则称Z是序列X与Y的公共子序列。例如序列"bcba"是序列"abcbdab"与"bdcaba"的公共子序列。例如,给出序列X "hahafdreghsbacdba"和序列"acdbegshbdrabsa",如何求取这两个序列的最长公共子序列?

这道题具有典型的最优子结构特性,即它的最优解一定包含子问题的最优解,这么看使用动态规划来解决是比较合理的。动态规划解题步骤通常由三个部分构成

1. 分阶段。

2. 状态迁移方程。

3. 寻找最优解。

对于这道题,字符数组a存储序列X,数组b存储序列Y,设i, j分别为数组a, b的指针。m[i][j]表示序列a[0] ~ a[i]与序列b[0]~b[j]的最长公共子序列,当a[i] == b[i]时,俩字符相等,最长公共子序列等于m[i-1][j-1] + 1; 如果字符不等,则

m[i][j] = MAX(m[i-1][j], m[i][j-1]);这个就是状态迁移方程。得到了状态迁移方程,在开始递推之前,需要知道边界情况,这里的边界情况就是当i等于0时,对于任意的0 <= j <= len(b), m[i][j] = 0; 同理,当j = 0时,任意的0 <= i <= len(a), m[i][j] = 0。对于字符串而言,数组下标为0是有字符的,所以说这么算会带来处理上的不方便,既然顺序不方便那就是用倒序好了,假设m[i][j]表示序列a[i] ~ a[last]与序列a[j][last]的最长公共子序列长度,当i = len(a)的时候,任意的j值,m[i][j] = 0,这个也很好理解,i等于n,说明a里面没有字符,这时候对于任意的j值,m[i][j] = 0,同理对于j = len(b),此时任意的i值,m[i][j] = 0。通常使用动态规划解决问题的时候,都存在两种递推方式,顺序递推和逆序递推,具体使用哪种根据具体问题来决定。

得到状态迁移方程,就可以知道最优解了,即m[0][0];接下来就是打印最优解序列了,这个可以根据状态迁移方程来判断哪个字符在最优解序列中。

下面是该问题的c代码实现:

//最长公共子串的动态规划解法#include <stdio.h>#include <string.h>#define MAX(a, b) ((a) > (b) ? (a) : (b))void main(){int i, j, k, n, m[30][30] = {0};char astr[30+1] = "hsbafdreghsbacdba", bstr[30+1] = "acdbegshbdrabsa";n = strlen(astr);k = strlen(bstr);printf("string A : %s\n", astr);printf("string B : %s\n", bstr);//边界初始化for (i = 0; i < n; i++)m[i][k] = 0;for (j = 0; j < k; j++)m[n][j] = 0;//状态递推for (i = n - 1; i >= 0; i--){for (j = k - 1; j >= 0; j--){if (astr[i] == bstr[j])m[i][j] = m[i+1][j+1] + 1;elsem[i][j] = MAX (m[i+1][j], m[i][j+1]);}}//打印最优解printf("最长公共子串长度为:%d\n", m[0][0]); for (i = 0; i < n;){for (j = 0; j < k;){if (astr[i] == bstr[j]){printf("%c", astr[i]);i++;j++;}else{if (m[i][j] == m[i+1][j])i++;elsej++;}}}printf("\n");return;}

参考资料:

1.数据结构: C语言版/ 严蔚敏,吴伟民编著

=============================================================================================

Linux应用程序、内核、驱动开发交流讨论群(745510310),感兴趣的同学可以加群讨论、交流、资料查找等,前进的道路上,你不是一个人奥^_^。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。