点击打开链接
题意:给出两个串让你再不破坏每个串的字符顺序的情况下 输出一个由两个串组成的新串(保证新串长度最小)
最长公共子串变形 ,通过最长公共子串的方式找到相同字符的坐标位置,然后通过插入的方式将新串输出
方法一:
#include<bits/stdc++.h> #define INF 0x3f3f3f3f #define MAXN 1000 using namespace std; int dp[MAXN][MAXN]; struct node { int x,y; } p[MAXN]; char s1[MAXN],s2[MAXN]; int vis[1000][1000]; int main() { while(~scanf("%s%s",s1,s2)) { memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); int len1=strlen(s1); int len2=strlen(s2); int top=1; p[0].x=0; p[0].y=0; for(int i=0; i<len1; i++) { for(int j=0; j<len2; j++) { if(s1[i]==s2[j]) ///最长公共子序列 { dp[i][j]=dp[i-1][j-1]+1; p[top].x=i; ///记录s1[i]与s2[j]相同的坐标 p[top].y=j; vis[i][j]=top++; ///记录存放坐标的数组下标 } else { if(dp[i-1][j]>dp[i][j-1]) { dp[i][j]=dp[i-1][j]; vis[i][j]=vis[i-1][j]; } else { dp[i][j]=dp[i][j-1]; vis[i][j]=vis[i][j-1]; } } } } stack<int>Q; ///将存入的坐标的数组下标reserve反转 int next2=vis[len1-1][len2-1]; while(next2>0) { Q.push(next2); if(p[next2].x-1>=0&&p[next2].y-1>=0) next2=vis[p[next2].x-1][p[next2].y-1]; else break; } int next1=0,next=0; int flag=1,i=0,j=0; while(!Q.empty()) ///将新串输出 { next=Q.top(); ///相同字符的坐标 Q.pop(); for(i=p[next1].x; i<p[next].x; i++) ///输出中间存在的不相同的字符 printf("%c",s1[i]); //cout<<endl; if(flag) { if(p[next1].y<p[next].y) ///防止重复输出公共字符 printf("%c",s2[p[next1].y]); flag=0; } for(j=p[next1].y+1; j<p[next].y; j++) printf("%c",s2[j]); // cout<<endl; next1=next; } if(s1[i]==s2[j]) ///防止重复输出公共字符 j++; for(i; i<len1; i++) printf("%c",s1[i]); for(j; j<len2; j++) printf("%c",s2[j]); printf("\n"); } return 0; }
方法二 #include<bits/stdc++.h> int dp[111][111]; int pre[111][111]; char str1[111],str2[111]; void P(int i,int l) { if(i==0&&l==0) return ; if(pre[i][l]==1) {P(i,l-1);printf("%c",str2[l]);} else if(pre[i][l]==3) {P(i-1,l);printf("%c",str1[i]);} else {P(i-1,l-1);printf("%c",str1[i]);} } int main() { int i,l; int len1,len2; while(scanf("%s%s",&str1,&str2)!=-1) { len1=strlen(str1); len2=strlen(str2); for(l=len1;l>0;l--) str1[l]=str1[l-1]; for(l=len2;l>0;l--) str2[l]=str2[l-1]; memset(dp,0,sizeof(dp)); memset(pre,0,sizeof(pre)); for(l=0;l<=len1;l++) pre[l][0]=3; for(l=0;l<=len2;l++) pre[0][l]=1; for(i=1;i<=len1;i++) { for(l=1;l<=len2;l++) { if(str1[i]==str2[l]) {dp[i][l]=dp[i-1][l-1]+1;pre[i][l]=2;} else if(dp[i][l-1]>dp[i-1][l]) {dp[i][l]=dp[i][l-1];pre[i][l]=1;} else {dp[i][l]=dp[i-1][l];pre[i][l]=3;} } } P(len1,len2); printf("\n"); } return 0; }