1. 题目
在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。
现在,给定一个由许多词根组成的词典和一个句子。你需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。
你需要输出替换之后的句子。
输入: dict(词典) = ["cat", "bat", "rat"]
sentence(句子) = "the cattle was rattled by the battery"
输出: "the cat was rat by the bat"
注:
输入只包含小写字母。
1 <= 字典单词数 <=1000
1 <= 句中词语数 <= 1000
1 <= 词根长度 <= 100
1 <= 句中词语长度 <= 1000
2. Trie解题
参考:Trie树
- 先将单词插入Trie树
- 然后依次查询每个单词的各前缀是否在Trie中,进行替换
class TrieNode//节点
{
public:
char ch;
TrieNode *next[26];
bool isEnd;
TrieNode(char c = '/'):ch(c),isEnd(false)
{
memset(next, 0, sizeof(TrieNode*)*26);
}
};
class Trie//Trie树
{
public:
TrieNode *root;
Trie()
{
root = new TrieNode();
}
~Trie()//析构释放内存
{
destroy(root);
}
void destroy(TrieNode *root)
{
if(root == NULL)
return;
for(int i = 0; i < 26; i++)
destroy(root->next[i]);
delete root;
}
void insert(string str)//插入单词
{
TrieNode *cur = root;
for(char s:str)
{
if(cur->next[s-'a'] == NULL)
cur->next[s-'a'] = new TrieNode(s-'a');
cur = cur->next[s-'a'];
}
cur->isEnd = true;
}
};
class Solution {
Trie tree;
public:
string replaceWords(vector<string>& dict, string sentence) {
for(string s:dict)
tree.insert(s);
string word, ans, prefix;
TrieNode *cur = tree.root;
istringstream in(sentence);
int i, chIdx;
while(in >> word)
{
cur = tree.root;
prefix = "";
for(i = 0; i < word.size(); ++i)
{
chIdx = word[i]-'a';
if(cur->next[chIdx] == NULL)
{
ans += word;
break;
}
else
{
prefix.push_back(word[i]);
if(cur->next[chIdx]->isEnd)
{
ans += prefix;
break;
}
if(i == word.size()-1)//最后一个字符特殊处理
ans += prefix;
}
cur = cur->next[chIdx];
}
ans.push_back(' ');
}
ans.pop_back();//删除空格
return ans;
}
};