最长连续公共子序列

来源:互联网 发布:淘宝天天疯狂购 编辑:程序博客网 时间:2024/05/01 22:25

在上一篇已经讲述过最长公共非连续子序列计算公式为:


而对于最长公共连续子序列,实现的公式为:


比较后,将数据的比较结果存放到二维数组中:


实现代码为:时间复杂度和空间复杂度都是O(m*n)

#include<iostream>#include<vector>#include<string>#include<stack>using namespace std;void longestComSubConstantSequce(string str1, string str2){int m=str1.length();int n=str2.length();int maxLen=0;int maxIdxX=0;int maxIdxY=0;stack<char> s;vector<vector<int>> vec(m+1, vector<int>(n+1, 0));for(int i=1; i<m+1; i++){for(int j=1; j<n+1; j++){if(str1[i-1]==str2[j-1]){vec[i][j]=vec[i-1][j-1]+1;if(maxLen<vec[i][j])//计算时,统计最长连续公共子序列的下标以及长度{maxLen=vec[i][j];maxIdxX=i;maxIdxY=j;}}elsevec[i][j]=0;//主要区别}}for(int i=maxIdxX, j=maxIdxY; vec[i][j]>0; i--, j--)//最后根据{s.push(str1[i-1]);}while(!s.empty()){cout<<s.top()<<"\t";s.pop();}cout<<endl;}void main(){string str1="lelowpworldsan";string str2="oknowworldss";longestComSubConstantSequce(str1, str2);}

以上方法占用空间较大,这里采用O(N)空间实现:

//保证s1长度大于p1void lcs(char * s1, char *p1){int len1=strlen(s1);int len2=strlen(p1);int comm_len=min(len1, len2);int curMaxIdx=-1;int maxLen=-1;vector<int> lastLine(comm_len, 0);vector<int> curLine(comm_len, 0);cout<<"\t";for(int i=0; i<len2; i++)cout<<p1[i]<<"\t";cout<<endl;for(int i=0; i<len1; i++){//这里需要保证len1>len2,否则会出错,除非定义curLine时,长度去两个字符串较长者cout<<s1[i]<<"\t";if(s1[i]==p1[0])curLine[0]=1;elsecurLine[0]=0;cout<<curLine[0]<<"\t";for(int j=1; j<len2; j++){if(s1[i]==p1[j]){curLine[j]=lastLine[j-1]+1;if(curLine[j]>maxLen){maxLen=curLine[j];curMaxIdx=j-maxLen+1;}}else{curLine[j]=0;}cout<<curLine[j]<<"\t";}cout<<endl;lastLine=curLine;}for(int i=curMaxIdx; i<curMaxIdx+maxLen; i++){cout<<p1[i];}cout<<endl;}void main(){char * s1="helojworldss";char * p1="helworldss";lcs(s1, p1);}




0 0