POJ_2250_LCS

//============================================================================
// Name        : POJ_2250_LCS.cpp
// Author      : tiger
// Version     :
// Copyright   : 最长公共子串
// Description : 将每个单词看做一个字符,求最大公共子串,关键是记录路径
//      用record[][]记录,当s1[i]==s2[j]时,cmp[i][j]得值来自于cmp[i-1][j-1]+1
//    ,则record[i][j] = 2;当s1[i]!=s2[j]时,如果cmp[i][j]得值来自于
//    cmp[i-1][j],则record[i][j] = 3;如果cmp[i][j]得值来自于
//    cmp[i][j-1],则record[i][j] = 1;如果cmp[i][j]得值来自于
//    cmp[i-1][j-1],则record[i][j] = 2;
//    这样从后向前推,就能找到所求,数据较弱
//============================================================================

#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
char s1[101][31];
char s2[101][31];
int cmp[101][101];
int record[101][101];
int len1,len2;
int LCS(int *maxi,int *maxj)
{
 memset(cmp,0,sizeof(cmp));

 int i,j,k;
 int max = 0;
 for(i = 0; i < len1; i++)
 {
  for(j = 0; j < len2; j++)
  {
   if(strcmp(s1[i],s2[j]) == 0 )
   {
    if(i ==0 || j == 0)
    {
     cmp[i][j] = 1;
    }
    else
    {

     cmp[i][j] = cmp[i-1][j-1] +1;
    }
     record[i][j] = 2;
    if(cmp[i][j] > max)
    {
     max = cmp[i][j];
     *maxi = i;
     *maxj = j;
    }

   }else
   {
    k = 0;
    if(i > 0 && cmp[i-1][j] > k)
    {

     k = cmp[i-1][j];
     record[i][j] = 3;
    }
    if(j > 0 && cmp[i][j-1] > k)
    {
      k = cmp[i][j-1];
      record[i][j] = 1;

    }
    if(j > 0 && i > 0 && cmp[i-1][j-1] > k)
    {

      k = cmp[i-1][j-1];
      record[i][j] = 2;
    }
    cmp[i][j] = k;

   }
  // printf("%d ",record[i][j]);
  }
  //printf("/n");
 }
 return max;//返回LCS长度
}


int main() {

 freopen("in","r",stdin);
 int i,j,k,max;
 int ans[101];
 while(scanf("%s",s1[0]) != EOF)
 {
  len1 = 1;
  while(scanf("%s",s1[len1]) && s1[len1][0] != '#')
  {
   len1++;
  }
  len2 = 0;
  while(scanf("%s",s2[len2]) && s2[len2][0] != '#')
  {
   len2++;
  }

  max = LCS(&i,&j);
  //从后向前查找LCS,并记录其在s2中的下标于ans[]
  k = 0;
  for( ;i >= 0 && k < max; )
  {
   for( ; j >= 0 && k < max; )
   {
    if(record[i][j] == 2)
    {
     ans[k++] = j;

     i--;j--;
    }
    else
     if(record[i][j] == 3)
     {
      i--;
     }else
      j--;
   }
  }
  while(k > 0)
  {
   k--;
   printf("%s ",s2[ans[k]]);
  }
  printf("/n");


 }
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值