首先说明前缀树,字典树是可以用来干嘛的?
对字符串进行记录,字典排序。
前缀树,又称字典树。它是一棵 N 叉树。前缀树用于存储、查找字符串。前缀树的每一个结点代表一个字符串的前缀。每一个结点会有多个子结点,通往不同子结点的路径上有着不同的字符。子结点代表的字符串是由结点本身的原始字符串 ,以及通往该子结点路径上所有的字符组成的。
转载了代码Tire前缀树,然后添加了一些注释。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAX_NODE = 1000000 + 10;
const int CHARSET = 26;
int trie[MAX_NODE][CHARSET] = {0};
int color[MAX_NODE] = {0};
int k = 1; //节点序号
//掺入字符串w
void insert(char *w){
int len = strlen(w); //字符串长度
int p = 0;
for(int i=0; i<len; i++){
int c = w[i] - 'a';
if(!trie[p][c]){ //节点p是否有字符为c的边
trie[p][c] = k; //如果没有边就新建一个字符串
k++; //整体节点序号++
}
p = trie[p][c]; //到下一个节点
}
color[p] = 1; //标记该序号的节点为终止节点
}
int search(char *s){
int len = strlen(s);
int p = 0;
for(int i=0; i<len; i++){
int c = s[i] - 'a';
if(!trie[p][c]) return 0; //没有该子串的字符串
p = trie[p][c];
}
return color[p] == 1; //有含该子串的字符串,但并没有中止
}
int main(){
int t,q;
char s[20];
scanf("%d%d", &t,&q);
while(t--){
scanf("%s", s);
insert(s);
}
while(q--){
scanf("%s", s);
if(search(s)) printf("YES\n");
else printf("NO\n");
}
return 0;
}
另外的一种写法,更加优雅的方法。
Leetcode472号
struct Trie {
bool isEnd;
vector<Trie *> children;
Trie() {
this->children = vector<Trie *>(26, nullptr);
this->isEnd = false;
}
};
class Solution {
public:
Trie * trie = new Trie();
vector<string> findAllConcatenatedWordsInADict(vector<string>& words) {
vector<string> ans;
sort(words.begin(), words.end(), [&](const string & a, const string & b){
return a.size() < b.size();
});
for (int i = 0; i < words.size(); i++) {
string word = words[i];
if (word.size() == 0) {
continue;
}
if (dfs(word, 0)) {
ans.emplace_back(word);
} else {
insert(word);
}
}
return ans;
}
bool dfs(const string & word, int start) {
if (word.size() == start) {
return true;
}
Trie * node = trie;
for (int i = start; i < word.size(); i++) {
char ch = word[i];
int index = ch - 'a';
node = node->children[index];
if (node == nullptr) {
return false;
}
if (node->isEnd) {
if (dfs(word, i + 1)) {
return true;
}
}
}
return false;
}
void insert(const string & word) {
Trie * node = trie;
for (int i = 0; i < word.size(); i++) {
char ch = word[i];
int index = ch - 'a';
if (node->children[index] == nullptr) {
node->children[index] = new Trie();
}
node = node->children[index];
}
node->isEnd = true;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/concatenated-words/solution/lian-jie-ci-by-leetcode-solution-mj4d/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。