基于动态规划的最长公共子序列实现(LCS)

来源:互联网 发布:js正则验证身份证号码 编辑:程序博客网 时间:2024/05/21 10:31

问题描述:

在生物学中,经常要通过比对DNA序列来得到两个DNA的相似度,其中一种方式是寻找两个子序列的最长公共子序列来衡量相似度。
例如:1:ACGCGCGCGAC  2:ACGCTTTTTTTT 的最长公共子序列就是 3:ACGC

Input:
ACGCGCGCGAC
ACGCTTTTTTTT

Output:
ACGC
//自底向上经典动态规划的实现
#include<iostream>#include<string>#include<stack>using namespace std;int c[100][100];char b[100][100];void lcs_length(string &a, string &B){int aL = a.length();int bL = B.length();for (int i=1;i<100;i++)c[i][0] = 0;for (int j=0;j<100;j++)c[0][j] = 0;for(int i=1;i<aL;i++){for(int j=1;j<bL;j++){if(a.at(i) == B.at(j)){c[i][j] = c[i-1][j-1] +1;b[i][j] = 'A';}else if(c[i-1][j] >= c[i][j-1]){c[i][j] = c[i-1][j];b[i][j] = 'B';}else{c[i][j] = c[i][j-1];b[i][j] = 'C';}}}}string store;void print(char b[][100],string a,int i,int j){if(i == 0 || j==0){return;}if(b[i][j] == 'A'){print(b,a,i-1,j-1);cout << a.at(i); }else if(b[i][j] == 'B'){print(b,a,i-1,j);}else{print(b,a,i,j-1);}}int main(){string A,B,C;while(cin >> A >> B){A = " "+A;B = " "+B;lcs_length(A,B);print(b,A,A.length()-1,B.length()-1);}}


//基于备忘录的自顶向下方法的实现
#include<iostream>#include<string>using namespace std;string s[100][100];//备忘录,存储计算过的子问题解void compare(string &a, string &b)//总之把长的字符串设为a,短的设为b{string temp;if (b.length() > a.length()){temp = b;b = a;a = temp;}}bool match(string &a, string &b, int &j)//用b字符串的最后一个字符去逐个匹配a的每一个字符,匹配成功返回true,另外返回匹配到的a中字符的位置j{char temp = b.at(b.length()-1);for(int i=a.length()-1; i>=0;i--){if(temp == a.at(i)){j = i;return true;}}return false;}string lcs(string &a, string &b){if(a.empty() || b.empty())//若任何一个字符串为空则直接返回{return "";}int j;bool flag = match(a,b,j);if(flag == false){if(s[a.length()][b.length()-1] != ""){return s[a.length()][b.length()-1];}else{string app = lcs(a,b.substr(0,b.length()-1));s[a.length()][b.length()-1] =  app;return app;}}else{if(s[a.length()-1][b.length()-1] != ""){return s[a.length()-1][b.length()-1];}else{string app = lcs(a.substr(0,a.length()-1),b.substr(0,b.length()-1));s[a.length()-1][b.length()-1] = app+b.at(b.length()-1);return app+b.at(b.length()-1);}}}int main(){string a,b,c;for(int i=0;i<100;i++){for(int j=0;j<100;j++){s[i][j] = "";}}while(cin >> a >> b){compare(a,b);c = lcs(a,b);cout << c << endl;}}

参考文献:
《算法导论 第三版》 动态规划


原创粉丝点击