UVA 10100; 链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1041
题目:
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: 12. Blank!
3. Length of longest match: 2
解题思路:
这是一道最长公共子串的问题,题目要求求出最多的单词匹配个数,我们可以把单词看成字母,这样就转化成了一个求最长公共子串的问题了。因此,我们需要一点处理,先将读取到的字符串处理一下,使其成为一个二维字符数组,每个单词作为这个字符数组的一个元素。接下来就可以直接用动态规划来处理了。
代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
#define max(x,y) x>y?x:y
const int MAXN = 1024;
struct text
{
int num;
string a[MAXN];
};
text texta, textb;
string stra, strb;
int dp[MAXN][MAXN];
void devide(text &t, string s)
{
t.num = 1;
for(int i = 0; i < MAXN; i++)
t.a[i].clear();
int len = s.length();
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.a[t.num] += s[i];
}
else
{
t.num++;
}
}
int now = 0;
for(int i = 1; i <= t.num; i++)
{
if(!t.a[i].empty())
{
now++;
t.a[now] = t.a[i];
}
}
t.num = now;
}
int main()
{
int t = 1;
while(!cin.eof())
{
getline(cin, stra);
getline(cin, strb);
devide(texta, stra);
devide(textb, strb);
printf("%2d. ", t++);
if(0 == texta.num || 0 == textb.num)
{
printf("Blank!\n");
}
else
{
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= texta.num; i++)
{
for(int j = 1; j <= textb.num; j++)
{
// cout << texta.a[i] << " " << textb.a[j] << endl;
if(texta.a[i] == textb.a[j])
{
dp[i][j] = dp[i-1][j-1] + 1;
}
else
{
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
}
printf("Length of longest match: %d\n",
dp[texta.num][textb.num]);
}
}
return 0;
}