微软100题(56)最长公共子序列

来源:互联网 发布:erp企业管理系统源码 编辑:程序博客网 时间:2024/06/05 08:55

题目:如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,

则字符串一称之为字符串二的子串。

注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中。
请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。

例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子串,
则输出它们的长度4,并打印任意一个子串。


思路:典型的动态规划题目,用c[i][j]代表a[i-1]和b[j-1]结尾的串的最长个数,显然,i==0或者j==0都是0,没有公共的, a[i-1]==b[j-1] c[i][j]=c[i-1][j-1]+1; a[i-1]!=b[j-1],那么c[i][j]就是取c[i-1][j]和c[i][j-1]中较大的那个

状态转移方程即是。

int LongestCommonSeq(char* a,int len1,char* b,int len2){vector<vector<int> > dp(len1+1,vector<int>(len2+1,0));for (int i= 0;i<=len1;++i){for (int j=0;j<=len2;++j){if(j==0||i==0) dp[i][j] = 0;else{if(a[i-1]==b[j-1]) dp[i][j] = dp[i-1][j-1] + 1;elsedp[i][j] = max(dp[i-1][j],dp[i][j-1]);}}}int maxlen = dp[len1][len2];//打印int k = dp[len1][len2];int m = len1;char* answer = new char[k+1];answer[k] = '\0';while (k>0){if(dp[len1][len2]==dp[len1-1][len2]) len1--;else if(dp[len1][len2]==dp[len1][len2-1]) len2--;else{k--;answer[k] = a[len1-1];len1--;len2--;}}cout<<answer<<endl;return maxlen;}



0 0