这道题也是一道前缀树类型的题目。先参考这题
主要在于如何去利用这个数据结构,这个结构的主要操作是,建树、查找。要处理的地方在于怎么迁移到这道题目上面来。观察题意,我们可以用pass 和end 来辅助处理。如何理解?
首先是建树,建树的过程和上一道的前缀树是一样的(当然在处理之前,要思考,是字典作为树,还是句子中的单词作为树),用句子中单词建树,数据量会很大,而且有多余的部分(分析实例,其中有很多没有词根的是直接输出的,因此我们建树的话,待会这个树会很庞大,且很多枝干是多余的存在的),反过来看,用词根建树,每个词根在树中是有存在的意义的。用句子中的单词在这颗树中查询。效率很高很多,比如首字母就查找不到,直接退出!
其次,如何用上pass end ,pass 代表词根中有经过这个字母,end代表词根中有以此字母为结束的(是遍历每个词根中的每个字母,建树的过程)
第三,将句子中的单词提取出来。
第四,在建好的词根树中,查询每个单词。pass不为0时,加入到一个新的字符串中(加入到尾部),如果end不为0 ,说明词根存在,赶紧输出前面的新字符串中。
第五,如果没有找到词根(其中包括,1.首字母就不匹配。2.词根前部分匹配,后半部分不匹配),则输出原来的单词。
typedef struct node{
int pass;
int end;
//bool flag = false; //判断是否结束
struct node* next[26] = {nullptr};
node(int a,int b):pass(a),end(b){}
}Node;
class Solution {
public:
Solution() //构造函数
{
node_shou = new Node(0,0);
}
string replaceWords(vector<string>& dictionary, string sentence) {
//建立前缀树
build_trie(dictionary);
//将句子切分
vector<string> mystr;
vector<int> biaoding;
for(int i = 0;i<sentence.size();i++)
if(sentence[i] == ' ')biaoding.emplace_back(i);
biaoding.emplace_back(sentence.size());
int chushi = 0;
for(int j = 0;j<biaoding.size();j++)
{
string mid(sentence.begin()+chushi,sentence.begin()+biaoding[j]);
mystr.emplace_back(mid);
chushi = biaoding[j]+1;
}
/*for(string i:mystr)
{
std::cout<<i<<std::endl;
}*/
//依次查询句子中成分,并合成句子
string out;
for(int k = 0;k<mystr.size();k++)
{
out += query(mystr[k]);
if(k == mystr.size()-1)break;
out.push_back(' ');
}
//返回句子
return out;
}
string query(string words) //查询,有词根就返回词根,没有就返回原单词
{
Node* node_2 = node_shou; //首节点
int index = 0;
string out;
for(int i = 0;i<words.size();i++)
{ index = words[i]-'a';
if(node_2->next[index] != nullptr )
{
if(node_2->next[index]->pass != 0)out.push_back(words[i]);
if(node_2->next[index]->end != 0)return out;
}
else
{
return words;
}
node_2 = node_2->next[index];
}
return words;
}
void build_trie(vector<string>& dictionary) //建树
{
for(int i = 0;i<dictionary.size();i++)
{
bulid(dictionary[i]);
}
}
void bulid(string str) //建枝叶
{
Node* node_1 = node_shou;
int index = 0;
for(int i = 0;i<str.size();i++)
{
index = str[i] - 'a';
if(node_1->next[index] == nullptr)//为空
{
if(i == str.size()-1)node_1->next[index] = new Node(1,1);
else
node_1->next[index] = new Node(1,0);
}
else//不为空
{
if(i == str.size()-1)
{
node_1->next[index]->end++;
}
node_1->next[index]->pass++;
}
node_1 = node_1->next[index];
}
}
private:
Node* node_shou;
};
代码有些冗余,如有大神指点,不胜感激呀~