最长公共子序列求解算法及代码实现
2017-11-30 17:44
471 查看
问题描述:
最长公共子序列问题是在2个序列集合中,查找最长的公共子序列。
比如字符串:
那么字符串s1与字符串s2的最长公共子序列就是
算法实现:
利用动态规划的方法实现(也叫打表法):2个字符串数组X[m]、Y
保存2个序列集合。用一个辅助二维数组,这个二维数组的L[i][j]保存的是X[0…i]和Y[0…j]中最长公共子序列的长度。
L[m]
的值就是lcs的长度。
解得构造:
这里构造解结构的时候和算法导论里的不一样,书里采用的是递归的方法构造,这里是采用了双指针遍历的方法也用到了辅助数组,但是辅助数组长度等于lcs的长度比书里的b数组要小。
为什么能这样做呢?也就是不用b数组保存一下“该怎么走”,我们怎么找到“路”,也就是lcs呢?别忘了b数组是怎么产生的!他是根据L数组的信息产生的。因为L数组的信息就告诉了我们“怎么走”,所以可以不要辅助数组b。
c++代码实现:
注:
构造解得时候只能打印出一个lcs,可能存在多个lcs序列。
这里L数组是100*100的,要保证100>=max{m,n}
最长公共子序列问题是在2个序列集合中,查找最长的公共子序列。
比如字符串:
s1="ABCDE" s2="ACEF"
那么字符串s1与字符串s2的最长公共子序列就是
"ACE"
算法实现:
利用动态规划的方法实现(也叫打表法):2个字符串数组X[m]、Y
保存2个序列集合。用一个辅助二维数组,这个二维数组的L[i][j]保存的是X[0…i]和Y[0…j]中最长公共子序列的长度。
L[m]
的值就是lcs的长度。
解得构造:
这里构造解结构的时候和算法导论里的不一样,书里采用的是递归的方法构造,这里是采用了双指针遍历的方法也用到了辅助数组,但是辅助数组长度等于lcs的长度比书里的b数组要小。
为什么能这样做呢?也就是不用b数组保存一下“该怎么走”,我们怎么找到“路”,也就是lcs呢?别忘了b数组是怎么产生的!他是根据L数组的信息产生的。因为L数组的信息就告诉了我们“怎么走”,所以可以不要辅助数组b。
c++代码实现:
/* Dynamic Programming implementation of LCS problem */ #include<iostream> #include<cstring> #include<cstdlib> using namespace std; /* L[i][j] store the length of LCS of X[0..i-1] and Y[0..j-1]*/ void lcsLength( int L[][100], char *X, char *Y, int m, int n ) { /* Following steps build L[m+1][n+1] in bottom up fashion. Note that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1] */ for (int i=0; i<=m; i++) { for (int j=0; j<=n; j++) { if (i == 0 || j == 0) L[i][j] = 0; else if (X[i-1] == Y[j-1]) L[i][j] = L[i-1][j-1] + 1; else L[i][j] = max(L[i-1][j], L[i][j-1]); } } } /*print the length of LCS and put out LCS */ void printLcs(int L[][100], char *X, char *Y, int m, int n){ // Following code is used to print LCS // L[m] stored the length of LCS int index = L[m] ; // Create a character array to store the lcs string char lcs[index+1]; lcs[index] = '\0'; // Set the terminating character // Start from the right-most-bottom-most corner and // one by one store characters in lcs[] int i = m, j = n; while (i > 0 && j > 0) { // If current character in X[] and Y are same, then // current character is part of LCS if (X[i-1] == Y[j-1]) { lcs[index-1] = X[i-1]; // Put current character in result char array i--; j--; index--; // reduce values of i, j and index } // If not same, then find the larger of two and // go in the direction of larger value // when add'=',the result is BCBA, just like the book;when it has no '=', the result is BDAB else if (L[i-1][j] >=L[i][j-1]) i--; else j--; } // Print the length of lcs and lcs cout<<"The length of LCS is "<<L[m] <<endl; cout << "LCS of " << X << " and " << Y << " is " << lcs; } /* Driver program to test above function */ int main() { char X[] = "ABCBDAB"; char Y[] = "BDCABA"; int m = strlen(X); int n = strlen(Y); int L[100][100]; lcsLength(L, X, Y, m, n); printLcs(L,X,Y,m,n); return 0; }
注:
构造解得时候只能打印出一个lcs,可能存在多个lcs序列。
这里L数组是100*100的,要保证100>=max{m,n}
相关文章推荐
- 二分图相关概念及匈牙利算法求解最大匹配(附代码实现)
- HMM求解观察序列概率的"前向算法"伪代码实现
- Trie树的应用,一道算法问题求解 代码实现
- 隐型马尔科夫模型(HMM)向前算法实例讲解(暴力求解+代码实现)---盒子模型
- HMM求解观察序列概率的"前向算法"伪代码实现
- 《剑指offer》66题JAVA代码算法实现全集
- 算法:集合的划分原理及代码实现
- 算法-java代码实现希尔排序
- 两种图像骨架提取算法的研究(2)实现代码
- 种子填充算法描述及C++代码实现
- 【裁剪】线段的裁剪——Cohen-Sutherland算法及代码实现
- 程序员必须知道的10大基础实用算法及其讲解(Javascript代码实现)
- A* 算法实现及代码下载(多种方式实现,加路径修正)
- 学习笔记——《机器学习实战》KNN算法实现 约会网站测试,手写数字识别,代码,注释,错误修改
- 基于OpenCV的人脸识别算法之二---代码实现
- 算法代码实现之选择排序,Java实现
- 基于GraphCuts图割算法的图像分割----OpenCV代码与实现
- KNN算法例子(java,scala,python 代码实现)
- 基于矩阵分解推荐算法之交替最小二乘法(ALS)--附实现代码
- 『HTML5实现人工智能』小游戏《井字棋》发布,据说IQ上200才能赢【算法&代码讲解+资源打包下载】