http://acm.hdu.edu.cn/showproblem.php?pid=1503
apple peach ananas banana pear peach
appleach bananas pearch
#include <stdio.h> #include <iostream> #include <string.h> using namespace std; char a[1005],b[1005]; int dp[1005][1005]; int x[1005][1005]; void print( int m,int n) { if(m==0&&n==0) return; else if(m==0&&n!=0) { print(m,n-1); printf("%c",b[n-1]); } else if(m!=0&&n==0) { print(m-1,n); printf("%c",a[m-1]); } else if(x[m][n]==0) { print(m-1,n-1); printf("%c",a[m-1]); } else if(x[m][n]==1) { print(m-1,n); printf("%c",a[m-1]); } else { print(m,n-1); printf("%c",b[n-1]); } } int main() { while(~scanf("%s%s",a,b)) { memset(dp,0,sizeof(dp)); int n=strlen(a); int m=strlen(b); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(a[i-1]==b[j-1]) { dp[i][j]=dp[i-1][j-1]+1; x[i][j]=0; } else if(dp[i-1][j]>=dp[i][j-1]) { dp[i][j]=dp[i-1][j]; x[i][j]=1; } else if(dp[i-1][j]<dp[i][j-1]) { dp[i][j]=dp[i][j-1]; x[i][j]=2; } } print(n,m); printf("\n"); } return 0; }
方法二:非递归输出的方法
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; #define size 201 struct rem { int i,j;/*i记录主串位置,j记录副串当前字符位置*/ char ch;/*记录当前字符*/ }; char a[size],b[size]; int dp[size][size]; rem ans[size]; int len;/*指示ans的长度*/ int main() { int a1,b1,i,j,k; while (scanf("%s%s",a+1,b+1)!=EOF) { a1 = strlen(a+1); b1 = strlen(b+1); memset(dp,0,sizeof(dp)); len = 0; for (i=1; i<=a1; i++) { for (j=1; j<=b1; j++) { if(a[i]==b[j]) dp[i][j] = dp[i-1][j-1]+1; else dp[i][j] = max(dp[i-1][j],dp[i][j-1]); } } /*取出最长公共子序列的字母*/ i = a1,j = b1; while (i!=0&&j!=0) { if ((dp[i][j] == dp[i-1][j-1]+1)&&a[i] == b[j]) { ans[len].i = i; ans[len].j = j; ans[len++].ch = a[i];/*倒序保存最长公共子序列字母*/ i--,j--; } else if(dp[i-1][j]>=dp[i][j-1]) i--; else j--; } /*取出最长公共子序列的字母*/ i = j = 1; for (k=len-1; k>=0; k--) { while (i!=ans[k].i)//此举是为了输出最长公共子序列之前和之中的非公共部分 { printf("%c",a[i]); i++; } while (j!=ans[k].j)//作用同上 { printf("%c",b[j]); j++; } printf("%c",ans[k].ch);//输出公共子序列的成员 i++,j++; } printf("%s%s\n",a+ans[0].i+1,b+ans[0].j+1);//输出最长公共子序列最后一个元素之后的非公共部分 } return 0; }