最长公共子序列(LCS)模板
程序员文章站
2024-01-14 14:22:22
...
HDU-1503
#include<bits/stdc++.h>
using namespace std;
int dp[105][105];
int main(){
string s1,s2;
while(cin>>s1>>s2){
memset(dp,0,sizeof(dp));
//构成dp表
for(int i=1;i<=s1.length();i++){
for(int j=1;j<=s2.length();j++){
if(s1[i-1]==s2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}
else {
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
//根据dp表寻找某一个最长子序列
stack<char> LCS;
for(int i=s1.length(),j=s2.length();j>=1&&i>=1;){
if(s1[i-1]==s2[j-1]){
LCS.push(s1[i-1]);
--i;--j;
}
else {//不相等时分类讨论
if(dp[i-1][j]==dp[i][j-1]){//统一选定一种方向 向左或向上
--j;
continue;
}
if(dp[i-1][j]==dp[i][j]){//如果是从dp[i-1][j]拓展出的dp[i][pj
--i;//向上移动一格
}
else {
--j;//向左移动一格
}
}
}
/*
while(!LCS.empty()){
char c=LCS.top();
LCS.pop();
cout<<c;
}
cout<<endl;
*/
int p1,p2;
p1=p2=0;
while(!LCS.empty()){
char c=LCS.top();
while(p1<s1.length()&&s1[p1]!=c){
printf("%c",s1[p1]);
p1++;
}
while(p2<s2.length()&&s2[p2]!=c){
printf("%c",s2[p2]);
p2++;
}
printf("%c",c);
LCS.pop();
p1++;p2++;
}
while(p1<s1.length()){
printf("%c",s1[p1]);
p1++;
}
while(p2<s2.length()){
printf("%c",s2[p2]);
p2++;
}
cout<<endl;
}
return 0;
}
没正式学习LCS前想当然的认为加维存储序列s1前i个字符与s2前j个字符能过,实际上后面的状态会覆盖掉前面已经存好的。
正解如上需要利用回溯的方法回推某个最长子序列。
错误代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
char dp[105][105][105];
int main(){
string s1,s2;
while(cin>>s1>>s2){
memset(dp,0,sizeof(dp));
s1+='_';
s2+='+';
int l1,l2;
l1=s1.length();
l2=s2.length();
int l=0;
for(int i=1;i<=l1;i++){
for(int j=1;j<=l2;j++){
int k=0;
while(dp[i-1][j-1][++k]!=0){
dp[i][j-1][k]=dp[i-1][j-1][k];
dp[i-1][j][k]=dp[i-1][j-1][k];
dp[i][j][k]=dp[i-1][j-1][k];
}
if(s1[i-1]==s2[j-1]){
dp[i][j][k]=s1[i-1];
l=k;
}
}
}
int p1,p2;
p1=p2=0;
for(int i=1;i<=l;i++){//l为lcs长度
while(p1<l1-1&&s1[p1]!=dp[l1-1][l2-1][i]){
printf("%c",s1[p1]);
p1++;
}
while(p2<l2-1&&s2[p2]!=dp[l1-1][l2-1][i]){
printf("%c",s2[p2]);
p2++;
}
printf("%c",dp[l1-1][l2-1][i]);
p1++;p2++;
}
while(p1<l1-1){
printf("%c",s1[p1]);
p1++;
}
while(p2<l2-1){
printf("%c",s2[p2]);
p2++;
}
cout<<endl;
}
return 0;
}
/*
appleananas bananapeach
cranberry boysenberry
nberry boysenberry
*/
上一篇: 里氏替换原则(LSP)
下一篇: 新年好兼散分兼提问.解决方法