Problem
有一个很长的由小写字母组成字符串。为了便于对这个字符串进行分析,需要将它划分成若干个部分,每个部分称为一个单词。
出于减少分析量的目的,我们希望划分出的单词数越少越好。你就是来完成这一划分工作的。
Input
第一行为一整数T,表示有T组测试数据。
每组测试数据第一行为一字符串。(长度小于256)
第二行为一整数N。(1<=N<=100)
以下N行,每行一个单词。
Output
一个整数,表示字符串可以被划分成的最少的单词数。
Sample Input
1
realityour
5
real
reality
it
your
our
Sample Output
2code:
#include <cstdio>
#include <cstring>
#include <set>
#include <functional>
using namespace std;
enum { MAX_LEN = 256 };
struct sless : public binary_function<const char*, const char*, bool>
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
int split_string(char* s, const set<const char*, sless>& words)
{
if (s == 0)
return 0;
int m[MAX_LEN] = {0};
int len = strlen(s);
for (int i = 0; i < len; ++i)
{
char ch = s[i+1];
s[i+1] = 0;
if (words.find(s) != words.end())
m[i] = 1;
else
{
int minimum = INT_MAX;
for (int j = i; j > 0; --j)
{
if (m[j-1] != 0 && words.find(s+j) != words.end())
minimum = min(m[j-1]+1, minimum);
}
m[i] = minimum;
}
s[i+1] = ch;
}
return m[len-1];
}
int main()
{
#if 0 // for lazy testing
char s[] = "realityour";
const char* words[] =
{
"real",
"reality",
"it",
"your",
"our",
0
};
set<const char*, sless> ws;
for (int i = 0; words[i] != 0; ++i)
ws.insert(words[i]);
int result = split_string(s, ws);
printf("result: %d\n", result);
#endif
int size;
scanf("%d", &size);
for (int i = 0; i < size; ++i)
{
char s[MAX_LEN] = {0};
scanf("%s", s);
int num;
scanf("%d", &num);
set<const char*, sless> ws;
for (int j = 0; j < num; ++j)
{
char* in = new char[128];
memset(in, 0, 128);
scanf("%s", in);
ws.insert(in);
}
printf("%d\n", split_string(s, ws));
}
}