写这篇文章不是因为我觉得最长公共子序列的资料还太少,
而是这么熟悉的问题我竟然WA了一上午才终于找到bug,
一上午的痛苦换来的教训:作为程序猿,即使面对再熟悉再简单的问题也要时刻保持严密的逻辑。
先上个有bug的代码吧
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 200
using namespace std;
string sa[N],sb[N],str;
int dp[N][N],ans[N];
struct node
{
int pa,pb;
}pre[N][N];
int main()
{
//freopen("8.in","r",stdin);
while(cin>>str) {
int la=0;
int lb=0;
sa[++la]=str;
while(cin>>str) {
if(str[0]=='#') break;
sa[++la]=str;
}
while(cin>>str) {
if(str[0]=='#') break;
sb[++lb]=str;
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=la;i++) {
for(int j=1;j<=lb;j++) {
int a=dp[i-1][j];
int b=dp[i][j-1];
int inc=0;
if(sa[i]==sb[j]) inc=1;
int c=dp[i-1][j-1]+inc;
if(a>b && a>c) {
dp[i][j]=a;
pre[i][j].pa=i-1;
pre[i][j].pb=j;
}
else if(b>a && b>c) {
dp[i][j]=b;
pre[i][j].pa=i;
pre[i][j].pb=j-1;
}
else {
dp[i][j]=c;
pre[i][j].pa=i-1;
pre[i][j].pb=j-1;
}
}
}
int p1,p2,cnt=0;
for(p1=la,p2=lb;p1>0 && p2>0;){
int np1=pre[p1][p2].pa;
int np2=pre[p1][p2].pb;
if(sa[p1]==sb[p2]) ans[cnt++]=p1;
p1=np1;
p2=np2;
}
//cout<<dp[la][lb]<<endl;
sort(ans,ans+cnt);
for(int i=0;i<cnt-1;i++) cout<<sa[ans[i]]<<" ";
cout<<sa[ans[cnt-1]]<<endl;
}
return 0;
}
AC的代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 200
using namespace std;
string sa[N],sb[N],str;
int dp[N][N],ans[N];
struct node
{
int pa,pb;
}pre[N][N];
int main()
{
//freopen("8.in","r",stdin);
while(cin>>str) {
int la=0;
int lb=0;
sa[++la]=str;
while(cin>>str) {
if(str[0]=='#') break;
sa[++la]=str;
}
while(cin>>str) {
if(str[0]=='#') break;
sb[++lb]=str;
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=la;i++) {
for(int j=1;j<=lb;j++) {
int a=dp[i-1][j];
int b=dp[i][j-1];
int inc=0;
if(sa[i]==sb[j]) inc=1;
int c=dp[i-1][j-1]+inc;
//问题就出在下面几个if-else语句中
if(c>a && c>b) {
dp[i][j]=c;
pre[i][j].pa=i-1;
pre[i][j].pb=j-1;
}
else if(b>a && b>c) {
dp[i][j]=b;
pre[i][j].pa=i;
pre[i][j].pb=j-1;
} else{
dp[i][j]=a;
pre[i][j].pa=i-1;
pre[i][j].pb=j;
}
}
}
int p1,p2,cnt=0;
for(p1=la,p2=lb;p1>0 && p2>0;){
int np1=pre[p1][p2].pa;
int np2=pre[p1][p2].pb;
if(sa[p1]==sb[p2] && p1>np1 && p2>np2) ans[cnt++]=p1;
p1=np1;
p2=np2;
}
sort(ans,ans+cnt);
for(int i=0;i<cnt-1;i++) cout<<sa[ans[i]]<<" ";
cout<<sa[ans[cnt-1]]<<endl;
}
return 0;
}