動態規劃求解最大公共子串和最大子序列問題
阿新 • • 發佈:2019-02-19
一.簡單的介紹
動態規劃一般用於求最優子結構問題,求全域性的解,可以通過求區域性的最優解,漸進的達到全域性的最優解。
最大公共子串 表示的是字串str1 和字串str2 之間存在重複的部分,但是重複的字串一定要是連續的,不能間斷。最大公共子序列表示的是字串str1 和字串str2 之間的是存在的字元相等,但是可以不要求是連續的。例如 str1 = "ABCAB"
str2 = "BCBD"。str1和str2之間的最大公共子串是"BC",str1和str2 之間的最大的公共子序列是"BCB".
二.下面舉個求最大公共子串的例子:
#include <iostream> #include <vector> #include <cstring> #include <string> using namespace std; string max_substr(string& str1,string& str2) { int len1 = str1.size(); int len2 = str2.size(); vector<int> last_vec(len1+1,0); //上一行 vector<int> cur_vec(len1+1,0); //當前行 int maxlen = 0; int pos = 0; for(int i =1;i<= len2;i++) //cdef { string s2 = str2.substr(i-1,1); for(int j = 1; j <= len1;j++) { string s1 = str1.substr(j-1,1); if(s2 == s1) { cur_vec[j] = last_vec[j-1] + 1; if(maxlen < cur_vec[j]) { maxlen = cur_vec[j]; pos = j; } } } last_vec = cur_vec; } cout << "**pos** :" << pos << "---maxlen--" << maxlen << endl; string res=str1.substr(pos-maxlen,maxlen); return res; } int main() { string str1("abcdef"); string str2("cdef"); string lcs = max_substr(str1,str2); cout<<lcs<<endl; return 0; }
執行的結果是: c d e f
三.看下求最大的子序列的例子(LCS)
執行的結果是:B D A B#include <iostream> #include <stdio.h> #include <string.h> using namespace std; #define MaxLen 50 int GetLcsLength(char* x,char* y,int c[][MaxLen], int b[][MaxLen]) { int m = strlen(x); int n = strlen(y); for(int i = 1;i<= m;i++) //x陣列 { char aa = x[i-1]; for(int j = 1;j <= n;j++) //y陣列 { char bb = y[j-1]; 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] = 3; //給出一個標記 } else { c[i][j] = c[i][j-1]; b[i][j] = 2; //給出一個標記 } } } return c[m][n]; //返回最大的值 } void printLcs(int b[MaxLen][MaxLen],char* x,int i ,int j) //傳入輔助的陣列b 和字串,從最後一個開始查詢 { if(i==0 || j ==0) //結束條件 return ; if(b[i][j] == 1) //表示相等的字元 { printLcs(b,x,i-1,j-1); cout << " " << x[i-1] << endl; } else if(b[i][j] == 2) { printLcs(b,x,i,j-1); } else { printLcs(b,x,i-1,j); } } int main() { char y[MaxLen] = {"ABCBDAB"}; char x[MaxLen] = {"BDCABA"}; int b[MaxLen][MaxLen] = {0}; int c[MaxLen][MaxLen] = {0}; int mm = strlen(x); int nn = strlen(y); cout << "****result****" << GetLcsLength(x,y,c,b) << endl; printLcs(b,x,mm,nn); return 0; }