看上去挺复杂的,将每个单词看做一个数组元素,将二维数组看做一维“字符串”,可以很显然的知道用lcs来做了。
还有个要注意的地方是输出时的格式控制,最后一个单词后没有空格输出,全部数据已文件末尾结束输入。
LCS要求打印出LCS串,在标记路径时也要认真点。
还有个要注意的地方是输出时的格式控制,最后一个单词后没有空格输出,全部数据已文件末尾结束输入。
LCS要求打印出LCS串,在标记路径时也要认真点。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
char temp[35];
char str1[110][35],str2[110][35];
int len1,len2,cnt;
int dp[110][110],path[110][110],pos[110];/*dp数组来存储LCS信息*/ /*path数值标记路径*/ /*pos记录LCS在串中的位置*/
int main()
{
void display_lcs(int a,int b);
while(scanf("%s",temp)!=EOF) /*将字符串按照单词个数进行分割,转化为lcs*/
{
len1 = 0; len2 = 0,cnt = 0;
strcpy(str1[++len1],temp);
while(scanf("%s",temp) && strcmp(temp,"#"))
{
strcpy(str1[++len1],temp);
}
while(scanf("%s",temp) && strcmp(temp,"#"))
{
strcpy(str2[++len2],temp);
}
memset(dp,0,sizeof(dp));
for(int i = 1 ; i <= len1 ; i++)/*求dp数组*/ /*所有下标全部是从1开始*/
{
for(int j = 1 ; j <= len2 ; j++)
{
if(!strcmp(str1[i],str2[j]))
{
dp[i][j] = dp[i-1][j-1] + 1;
path[i][j] = 1; /*记录路径的方向*/
}
else if( dp[i][j-1] >= dp[i-1][j])
{
dp[i][j] = dp[i][j-1];
path[i][j] = 2;/*记录路径的方向*/
}
else
{
dp[i][j] = dp[i-1][j];
path[i][j] = 3;/*记录路径的方向*/
}
}
}
display_lcs(len1,len2);/*打印LCS*/
for(int i = dp[len1][len2] ; i >= 1 ; --i)/*逆序输出*/
{
printf("%s",str1[pos[i]]);
if(i>1) /*最后一个不输出空格*/
{
cout<<" ";
}
}
cout<<endl;
memset(str1,0,sizeof(str1));
memset(str2,0,sizeof(str1));
memset(dp,0,sizeof(dp));
memset(path,0,sizeof(path));
memset(pos,0,sizeof(pos));
}
return 0;
}
void display_lcs(int i,int j) /*递归由后向前求出LCS各个值在某一串中的位置,标记在pos数组中*/
{
if(i ==0 && j ==0)
{
return;
}
if(path[i][j] == 1)
{
pos[++cnt] = i; /*pos[0]不存放信息,直接从pos[1]开始存放*/
display_lcs(i-1,j-1);
}
else if(path[i][j] == 2)
{
display_lcs(i,j-1);
}
else
{
display_lcs(i-1,j);
}
}