poj 2250 Compromise(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);
     }
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值