用动态规划法求两个字符串A="xzyzzyx"和B="zxyyzxz"的最长公共子序列,写出求解过程
时间: 2023-12-03 10:02:36 浏览: 394
动态规划法求字符串最长公共子序列
好的,我会根据您的要求来回答问题。
这里介绍一种使用动态规划来求解两个字符串的最长公共子序列的方法,这个方法被称为LCS算法(Longest Common Subsequence algorithm)。
首先,我们可以定义一个二维数组dp,其中dp[i][j]表示字符串A中前i个字符和字符串B中前j个字符的最长公共子序列的长度。接下来,我们可以使用以下的递推式来计算dp数组中的每一个元素:
- 当A[i] == B[j]时,dp[i][j] = dp[i-1][j-1] + 1
- 当A[i] != B[j]时,dp[i][j] = max(dp[i-1][j], dp[i][j-1])
其中,第一种情况表示当前字符相等,那么我们可以将这个字符加入到最长公共子序列中,并且将长度加1;第二种情况表示当前字符不相等,那么我们就要从A的前i-1个字符和B的前j个字符以及A的前i个字符和B的前j-1个字符中选取最长的公共子序列。
最后,dp[m][n]就是字符串A和B的最长公共子序列的长度,其中m和n分别是A和B的长度。
下面是字符串A和B的最长公共子序列的求解过程:
| | | z | x | y | y | z | x | z |
|---|---|---|---|---|---|---|---|---|
| | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| x | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
| z | 0 | 1 | 1 | 1 | 1 | 1 | 2 | 2 |
| y | 0 | 1 | 1 | 2 | 2 | 2 | 2 | 2 |
| z | 0 | 1 | 1 | 2 | 2 | 2 | 3 | 3 |
| z | 0 | 1 | 1 | 2 | 2 | 2 | 3 | 3 |
| y | 0 | 1 | 1 | 2 | 3 | 3 | 3 | 3 |
| x | 0 | 1 | 2 | 2 | 3 | 3 | 3 | 4 |
可以看到,dp[7][7]=4,也就是字符串A和B的最长公共子序列的长度为4。同时,我们可以根据dp数组中的元素来构造最长公共子序列,具体过程如下:
1. 从dp[7][7]开始,如果A[7] == B[7],那么就将这个字符加入到最长公共子序列中,并且将i和j分别减1,得到"z",dp[6][6]也是4,因此继续执行这个步骤;
2. 如果A[6] == B[6],那么将这个字符加入到最长公共子序列中,并且将i和j分别减1,得到"zy",dp[5][5]也是4,继续执行这个步骤;
3. 如果A[5] != B[5],那么就比较dp[5][4]和dp[4][5]的大小,发现它们相等,因此随便选一个,这里选择dp[5][4],将j减1,得到"z",dp[5][4]也是3,继续执行这个步骤;
4. 如果A[5] == B[4],那么将这个字符加入到最长公共子序列中,并且将i和j分别减1,得到"zyz",dp[4][3]也是3,继续执行这个步骤;
5. 如果A[4] == B[3],那么将这个字符加入到最长公共子序列中,并且将i和j分别减1,得到"zyzy",dp[3][2]也是2,继续执行这个步骤;
6. 如果A[3] != B[2],那么就比较dp[3][1]和dp[2][2]的大小,发现dp[3][1]更大,因此将i减1,得到"zyz",dp[3][1]也是1,继续执行这个步骤;
7. 如果A[3] == B[1],那么将这个字符加入到最长公共子序列中,并且将i和j分别减1,得到"zyzyx",dp[2][1]也是1,继续执行这个步骤;
8. 如果A[2] == B[0],那么将这个字符加入到最长公共子序列中,并且将i和j分别减1,得到"zyzyxz",dp[1][0]也是0,最长公共子序列的构造结束。
因此,字符串A和B的最长公共子序列为"zyzyxz",长度为4。
阅读全文