题目大意:输入所租测试用例,每组测试用例中输入两段文本,每段文本以“#”结束,要求输出这两段文本的最长公共子单词串。
算法思想:
DP
用char A[105][35],B[105][35]存储两段文本
.用m[i][j]存储A[i]和B[j]的最长公共子单词串的长度,由最优子结构性质(参见算法导论 DP LCS)可知 m[i][j]=m[i-1][j-1]+1 if(A[i]==B[i])
or= max(m[i-1][j],m[i][j-1]) i,j>=0 A[i]!=B[j]
代码如下:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
int c[105][105];
int m[105][105];
int Alen,Blen;
void LCSW(char A[105][35],char B[105][35],int a,int b){
for(int i=0;i<=a;i++){
c[i][0]=0;
}
for(int i=0;i<=b;i++){
c[0][i]=0;
}
for(int i=1;i<=a;i++){
for(int j=1;j<=b;j++){
if(strcmp(A[i],B[j])==0){
c[i][j]=c[i-1][j-1]+1;
m[i][j]=1;
}
else if(c[i-1][j]>=c[i][j-1]){
c[i][j]=c[i-1][j];
m[i][j]=2;
}
else{
c[i][j]=c[i][j-1];
m[i][j]=3;
}
}
}
}
void Print(char A[105][35],int i,int j){
if(i==0||j==0) return ;
if(m[i][j]==1){
Print(A,i-1,j-1);
printf("%s",A[i]);
if(i==Alen||j==Blen)printf("\n");//此处需要注意细节和格式
else printf(" ");
}
else if(m[i][j]==2){
Print(A,i-1,j);
}
else{
Print(A,i,j-1);
}
}
int main(){
char A[105][35],B[105][35];
char tmp[10];
while(~scanf("%s",tmp)){
Alen=0;
Blen=0;
Alen=(strcmp(tmp,"#")==0?0:1);
if(Alen) strcpy(A[1],tmp);
for(int i=Alen+1;Alen;i++){
scanf("%s",A[i]);
if(strcmp(A[i],"#")==0) break;
Alen++;
}
for(int i=1;;i++){
scanf("%s",B[i]);
if(strcmp(B[i],"#")==0) break;
Blen++;
}
LCSW(A,B,Alen,Blen);
Print(A,Alen,Blen);
}
return 0;
}