好题
刚开始是按照自己思路写的,因为不会记录路径
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; char str1[105],str2[105]; int t[110][110]; char a[110]; int main() { while(scanf("%s%s",str1,str2)!=EOF) { int len1=strlen(str1); int len2=strlen(str2); for(int i=0;i<len1;i++) for(int j=0;j<len2;j++) t[i][j]=0; for(int i=0;i<len1;i++) for(int j=0;j<len2;j++) if(str1[i]==str2[j]) t[i+1][j+1]=t[i][j]+1; else t[i+1][j+1]=max(t[i][j+1],t[i+1][j]); int pos=t[len1][len2]-1; int p=len1,k=len2; int tag1=1,tag2=1; while(t[p][k]){ if(t[p][k]==t[p][k-1]){ k--; tag2=0; } else if(t[p][k]==t[p-1][k]){ p--; tag1=0; } else{ if(tag1){ a[pos--]=str2[k-1]; p--; } else{ a[pos--]=str1[p-1]; k--; } tag1=1; tag2=1; } } int p1=0,p2=0; for(int i=0;i<len1;i++) if(a[0]==str1[i]){ p1=i; break; } else printf("%c",str1[i]); for(int j=0;j<len2;j++) if(a[0]==str2[j]){ p2=j; break; } else printf("%c",str2[j]); int i,j; pos=0; for(i=p1,j=p2;i<len1||j<len2;) if(str1[i]==a[pos]&&a[pos]==str2[j]&&i<len1&&j<len2){ printf("%c",str1[i]); i++; j++; pos++; } else{ if(i<len1&&str1[i]!=a[pos]) printf("%c",str1[i++]); else if(j<len2&&a[pos]!=str2[j]) printf("%c",str2[j++]); } puts(""); } return 0; }
后来在网上学习别人的代码,理解到了递归+回溯+记录路径的代码
#include<stdio.h> #include<string.h> char str1[105],str2[105]; int path[110][110]; void print(int n,int m){ if(!n&&!m) return ; if(path[n][m]==m+1){ print(n-1,m-1); putchar(str1[n]); } else if(path[n][m]==m){ print(n-1,m); putchar(str1[n]); } else{ print(n,m-1); putchar(str2[m]); } return ; } int main() { while(scanf("%s%s",str1+1,str2+1)!=EOF) { int len1=strlen(str1+1); int len2=strlen(str2+1); int t[110][110]={0}; for(int i=1;i<=len1;i++) for(int j=1;j<=len2;j++) if(str1[i]==str2[j]) t[i][j]=t[i-1][j-1]+1,path[i][j]=j+1; else if(t[i][j-1]>t[i-1][j]) t[i][j]=t[i][j-1],path[i][j]=j-1; else t[i][j]=t[i-1][j],path[i][j]=j; print(len1,len2); puts(""); } return 0; }