uva 10100 Longest Match(最长公共子序列)

17 篇文章 0 订阅

Longest Match

Input: standard input

Output: standard output


A newly opened detective agency is struggling with their limited intelligence to find out a secret information passing technique among its detectives. Since they are new in this profession, they know well that their messages will easily be trapped and hence modified by other groups. They want to guess the intensions of other groups by checking the changed sections of messages. First they have to get the length of longest match. You are going to help them.


Input

The input file may contain multiple test cases. Each case will contain two successive lines of string. Blank lines and non-letter printable punctuation characters may appear. Each Line of string will be no longer than 1000 characters. Length of each word will be less than 20 characters.


Output

For each case of input, you have to output a line starting with the case number right justified in a field width of two, followed by the longest match as shown in the sample output. In case of at least one blank line for each input output 'Blank!'. Consider the non-letter punctuation characters as white-spaces.


Sample Input

This is a test.
test
Hello!

The document provides late-breaking information
late breaking.


Sample Output

 1. Length of longest match: 1
 2. Blank!

 3. Length of longest match: 2


给定两行字符串序列,输出它们之间最大公共子单词的个数

对于给的两个序列X 和 Y,用i 和 j分别作为它们的前缀指针,f[i][j]表示序列X的前缀Xi 和 序列Y的前缀Yi 的最长公共子序列的长度,在这道题中,可把每一个单词当作一个字符来进行比较。

当 i || j 为0时 ,此 f[i][j] = 0;

当 i!=0 && j!=0 && Xi==Yi 时 f[i][j] = f[i-1][j-1] + 1;

当 i!=0 && j!=0 && Xi!=Yi 时 f[i][j] = max ( f[i-1][j] + f[i][j-1] );

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;

struct node
{
    int num;          //记录单词的个数
    string w[1010];   //单词序列
};
int f[1010][1010];    //Xi 中前i个单词 与 Yj 中前j个单词 最大公共子序列个数为f[i][j] 
void devide(string s,node &t)
{
    int len=s.size();
    t.num=1;
    for(int i=0; i<len; i++)
    {
        if( (s[i]>='a' && s[i]<='z') || (s[i]>='A' && s[i]<='Z') ||(s[i]>='0' && s[i]<='9') )
        {
            t.w[t.num]+=s[i];
        }
        else t.num++;
    }
    int n=0;
    for(int i=1; i<=t.num ; i++)
    {
        if(!t.w[i].empty())
            t.w[++n]=t.w[i];
    }
    t.num=n;
}
int main()
{
    int ca=1;
    while(!cin.eof())
    {
        string X,Y;
        node t1,t2;
        getline(cin,X);
        devide(X,t1);      //把x中的单词取出来
        getline(cin,Y);
        devide(Y,t2);       //同上
        printf("%2d. ",ca++);
        if(X.empty() || Y.empty())     
        {
            printf("Blank!\n");
            continue;
        }
        memset(f,0,sizeof(f));
        for(int i=1; i<=t1.num; i++)
            for(int j=1; j<=t2.num; j++)
            {                                        //计算前i个单词 和 前j个单词最大匹配数
                f[i][j]=max(f[i-1][j],f[i][j-1]);
                if(t1.w[i] == t2.w[j])
                    f[i][j]=max(f[i][j] , f[i-1][j-1]+1);
            }
        printf("Length of longest match: %d\n",f[t1.num][t2.num]);

    }
    return 0;
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值