本文主要是介绍求两个字符串的最长公共子序列 合工大 程序设计艺术实验四,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
求两个字符串的最长公共子序列.
X的一个子序列是相应于X下标序列{1, 2, …, m}的一个子序列,求解两个序列的所有子序列中长度最大的,例如输入:pear,peach输出pea.
首先你要明白什么是最长公共子序列,例如 asd5gd 和 s5666d 的最长公共子序列为s5d
在两个字符串中,有些字符会一样,可以形成的子序列也有可能相等,因此,长度最长的相等子序列便是两者间的最长公共字序列,其长度可以使用动态规划来求。
以s1={1,3,4,5,6,7,7,8},s2={3,5,7,4,8,6,7,8,2}为例。
借用《算法导论》中的推导图:
创建 DP数组C[][];
图中的空白格子需要填上相应的数字(这个数字就是c[i][j]的定义,记录的LCS的长度值)。填的规则依据递归公式,简单来说:如果横竖(i,j)对应的两个元素相等,该格子的值 = c[i-1,j-1] + 1。如果不等,取c[i-1,j] 和 c[i,j-1]的最大值。首先初始化该表:
然后,一行一行地从上往下填:
S1的元素3 与 S2的元素3 相等,所以 c[2,1] = c[1,0] + 1。继续填充:
S1的元素3 与 S2的元素5 不等,c[2,2] =max(c[1,2],c[2,1]),图中c[1,2] 和 c[2,1] 背景色为浅黄色。继续填充:
中间几行填写规则不变,直接跳到最后一行:
至此,该表填完。根据性质,c[8,9] = S1 和 S2 的 LCS的长度,即为5。
为了打印路径,所以在代码里增添了一个新的数组用来记录路径.
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAXLEN 100using namespace std;void LCSLength(char *x, char *y, int m, int n, int c[][MAXLEN], int b[][MAXLEN])
{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(x[i-1] == y[j-1]){c[i][j] = c[i-1][j-1] + 1;b[i][j] = 0;}else if(c[i-1][j] >= c[i][j-1]){c[i][j] = c[i-1][j];b[i][j] = 1;}else{c[i][j] = c[i][j-1];b[i][j] = -1;}}}
}void PrintLCS(int b[][MAXLEN], char *x, int i, int j)
{if(i == 0 || j == 0)return;if(b[i][j] == 0){PrintLCS(b, x, i-1, j-1);printf("%c ", x[i-1]);}else if(b[i][j] == 1)PrintLCS(b, x, i-1, j);elsePrintLCS(b, x, i, j-1);
}int main(int argc, char **argv)
{char x[MAXLEN];char y[MAXLEN];int b[MAXLEN][MAXLEN];int c[MAXLEN][MAXLEN];int m, n;cout << "请输入两个字符串:" << endl;scanf("%s", x);scanf("%s", y);m = strlen(x);n = strlen(y);LCSLength(x, y, m, n, c, b);cout << "两个字符串的最大公共子序列是:" ;PrintLCS(b, x, m, n);return 0;
}
参考博客:https://blog.csdn.net/someone_and_anyone/article/details/81044153?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159110780919725247601128%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=159110780919725247601128&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-4-81044153.first_rank_ecpm_v3_pc_rank_v3&utm_term=%E6%9C%80%E9%95%BF%E5%85%AC%E5%85%B1%E5%AD%90%E5%BA%8F%E5%88%97
这篇关于求两个字符串的最长公共子序列 合工大 程序设计艺术实验四的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!