本来想就地回了,无奈JavaEye的注册太繁琐了,贴在这里看看。
引用:
|
话说有个魔法字典,其中记录了一些魔力单词(字符串),如果一个句子(也是字符串)可以被完全分解为若干魔力单词的拼接,那么这个句子就是一条咒语。假设我们可以用常数时间查询魔力字典是否包含一个特定的单词,那么现在给你一个句子,让你写一个程序判断这个句子是否一条咒语。用动态规划可以解哦。
|
从i=1-n(n为句子字符串的长度),逐步推算前i个字符串组成的句子是否为咒语。对于前i个字符串,要么它本身是一个咒语,要么是一个咒语末尾加上一个字典里包含的单词。程序如下:
C++ 代码:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <set>
using namespace std;
bool IsIncantation(string const& sentence, set<string> magicDic)
{
size_t n = sentence.size();
if (n == 0)
return false;
vector<bool> incanBits(n);
incanBits[0] =
( magicDic.find(sentence.substr(0, 1)) != magicDic.end() );
for (size_t i = 1; i < n; ++i)
{
if ( (magicDic.find(sentence.substr(0, i + 1)) != magicDic.end()) )
{
incanBits[i] = true;
continue;
}
incanBits[i] = false;
for (size_t j = 0; j < i; ++j)
{
if (incanBits[j] == true &&
magicDic.find(sentence.substr(j + 1, i - j)) != magicDic.end())
{
incanBits[i] = true;
break;
}
}
}
//copy(incanBits.begin(), incanBits.end(), ostream_iterator<bool>(cout, " "));
return incanBits[n - 1];
}
int main()
{
string incants[] = { "Zeta", "Mo", "Ma", "Doc", "EEEEEE", "Ear" };
set<string> dic;
for (size_t i = 0; i < sizeof(incants)/sizeof(incants[0]); ++i)
dic.insert(incants[i]);
string sentence("MoMaMaMaDocEarEEEEEEZetaMoMo");
bool isIncant = IsIncantation(sentence, dic);
cout <<
"The sentence \"" << sentence <<
"\" " <<
(isIncant ?
"is " :
"is not ") << "an incantation" << endl;
system("pause");
}