动态规划——最长公共子序列
2016-03-29 00:00
232 查看
一个数列S,若分别是两个或多个已知序列的子序列,且是所有符合条件序列中最长的,则S称为已知序列的最长公共子序列。
最长公共子串:子串是串的一个连续的部分.
最长公共子序列:子序列则可以不必连续,而从序列中去掉任意的元素而获得新的序列。
如果要输出所有序列,请参考这篇博客。
str1[i-1]!=str2[j-1]且c[i-1][j]=c[j-1][i]的情况。
http://blog.chinaunix.net/uid-26548237-id-3374211.html
最长公共子串:子串是串的一个连续的部分.
最长公共子序列:子序列则可以不必连续,而从序列中去掉任意的元素而获得新的序列。
//只输出一个序列 #include<iostream> #include<iostream> #include<stdio.h> using namespace std; static const int max_int = 100; void LCS(char* str1, char* str2, int m, int n, int c[max_int + 1][max_int + 1], int b[max_int + 1][max_int + 1]) { 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 (str1[i-1] == str2[j-1]) {//这里下标容易错。 c[i][j] = c[i - 1][j - 1] + 1; b[i][j] = 0; } else { if (c[i][j - 1]>c[i - 1][j]) { c[i][j] = c[i][j - 1]; b[i][j] = -1; } else { c[i][j] = c[i - 1][j]; b[i][j] = 1; } } } } cout << "最长公共子序列大小为:" << c[m] << endl; } void Display_LCS(int b[max_int + 1][max_int + 1], char* str1, int i, int j) { if (i == 0 || j == 0) return; if (0 == b[i][j]) { Display_LCS(b, str1, i - 1, j - 1); cout << str1[i - 1]; } else if (-1 == b[i][j]) { Display_LCS(b, str1, i, j - 1); } else { Display_LCS(b, str1, i - 1, j); } } //不用递归,用个链表保存 void showLCS2(const vector<vector<int>> &d, const char *a, int m, int n) { list<char> ans; while (m > 0 && n > 0) { if (d[m] == 0) { ans.insert(ans.begin(),a[m]); --m; -n; } else if (d[m] == -1) { --n; } else { --m; } } for_each(ans.begin(), ans.end(), [](char a) {cout << a << endl;}); } int main() { char str1[max_int]; char str2[max_int]; scanf("%s", str1); scanf("%s", str2); int m = strlen(str1); int n = strlen(str2); int c[max_int + 1][max_int + 1]; int b[max_int + 1][max_int + 1]; LCS(str1, str2, m, n, c, b); Display_LCS(b, str1, m, n); cout << endl; return 0; }
如果要输出所有序列,请参考这篇博客。
str1[i-1]!=str2[j-1]且c[i-1][j]=c[j-1][i]的情况。
http://blog.chinaunix.net/uid-26548237-id-3374211.html
//求取所有的最长公共子序列 #include <iostream> using namespace std; const int X = 100, Y = 100; //串的最大长度 char result[X+1]; //用于保存结果 int count=0; //用于保存公共最长公共子串的个数 /*功能:计算最优值 *参数: * x:字符串x * y:字符串y * b:标志数组 * xlen:字符串x的长度 * ylen:字符串y的长度 *返回值:最长公共子序列的长度 * */ int Lcs_Length(string x, string y, int b[][Y+1],int xlen,int ylen) { int i = 0; int j = 0; int c[X+1][Y+1]; for (i = 0; i<=xlen; i++) { c[i][0]=0; } for (i = 0; i <= ylen; i++ ) { c[0][i]=0; } for (i = 1; i <= xlen; i++) { for (j = 1; j <= ylen; j++) { if (x[i - 1] == y[j - 1]) { c[i][j] = c[i-1][j-1]+1; b[i][j] = 1; } else if (c[i-1][j] > c[i][j-1]) { c[i][j] = c[i-1][j]; b[i][j] = 2; } else if(c[i-1][j] < c[i][j-1]) { c[i][j] = c[i][j-1]; b[i][j] = 3; } else { c[i][j] = c[i][j-1]; //或者c[i][j]=c[i-1][j]; b[i][j] = 4; } } } cout << "计算最优值效果图如下所示:" << endl; for(i = 1; i <= xlen; i++) { for(j = 1; j < ylen; j++) { cout << c[i][j] << " "; } cout << endl; } return c[xlen][ylen]; } /*功能:计算最长公共子序列 *参数: * xlen:字符串x的长度 * ylen:字符串y的长度 * x :字符串x * b:标志数组 * current_len:当前长度 * lcs_max_len:最长公共子序列长度 * */ void Display_Lcs(int i, int j, string x, int b[][Y+1],int current_len,int lcs_max_len) { if (i ==0 || j==0) { for(int s=0; s < lcs_max_len; s++) { cout << result[s]; } cout<<endl; count++; return; } if(b[i][j]== 1) { current_len--; result[current_len]=x[i- 1]; Display_Lcs(i-1, j-1, x, b,current_len,lcs_max_len); } else { if(b[i][j] == 2) { Display_Lcs(i-1, j, x, b,current_len,lcs_max_len); } else { if(b[i][j]==3) { Display_Lcs(i, j-1, x, b,current_len,lcs_max_len); } else { Display_Lcs(i,j-1,x,b,current_len,lcs_max_len); Display_Lcs(i-1,j,x,b,current_len,lcs_max_len); } } } } int main(int argc, char* argv[]) { string x = "ABCBDAB"; string y = "BDCABA"; int xlen = x.length(); int ylen = y.length(); int b[X + 1][Y + 1]; int lcs_max_len = Lcs_Length( x, y, b, xlen,ylen ); cout << lcs_max_len << endl; Display_Lcs( xlen, ylen, x, b, lcs_max_len, lcs_max_len ); cout << "共有:" << count << "种"; return 0; }
相关文章推荐
- Android学习-简易ViewPager的使用教程与Demo演示
- 检测哪里用到IDFA
- QT5的信号和槽.
- UITextField只要求输入数字和字母,并限制长度
- 被大家忽略的UITableViewHeaderFooterView,cell的展开和折叠
- 助你展翅翱翔,金鹰飞翔计划开始啦!
- 传统店家做电商不能只靠淘宝
- 安装dubbo管理控制台
- jsp页面的两种编码设置格式区别
- jsp错误页的设置
- EF分页查询
- Tomcat和JBoss都是服务器,有什么区别呢
- 字符串双向加密
- jq 选择器简单使用
- 验证所有类型的信用卡类
- 知道什么网站并发量吗?如何测试呢?这个必须了解了解。。。。
- 转:Selenium Webdriver使用技巧(一)
- kafka接入学习
- linux下PHP7环境搭建
- Python基础--图形用户界面GUI