力扣-208-实现Tire
和LRU一样是实现数据结构的题目
首先,对于树结构,我们要定义树节点:
- 前缀树是多叉树结构,所以子节点数不固定,这里用一个指向子节点的指针数组来保存子节点
为什么是长度伪26代表26个字母的定长数组?
- bool值,标记当前节点是否是结束位置,即:根节点到当前节点的路径字符串存在
vector<Trie*> children; bool isEnd;
因为封装了操作,所以才用类,而不是结构体吗?
来想一想为什么它这里用的是一个26长度的数组
因为这里的字符组成是固定的,这样做能最大优化空间占用,用数组下标(char当int操作ACSII码)确定字母
不然就要向那边一样,用map
插入
将一个字符串插入到前缀树中,即从头开始遍历字符串的每一个字符,从根节点的子节点开始比对,如果没有,就新加入一个,将指针更新为子节点,循环这一过程,并在结束后将最后一个节点的bool值置true
void insert(string word) { Trie* node = this; for (char ch: word) { ch -= 'a'; if (node->children[ch] == nullptr) node->children[ch] = new Trie(); node = node->children[ch]; } node->isEnd = true; }
完整代码
class Trie { private: vector<Trie*> children; bool isEnd; Trie* searchPrefix(string prefix) { Trie* node = this; for (char ch : prefix) { ch -= 'a'; if (node->children[ch] == nullptr) return nullptr; node = node->children[ch]; } return node; } public: Trie():children(26),isEnd(false){} void insert(string word) { Trie* node = this; for (char ch: word) { ch -= 'a'; if (node->children[ch] == nullptr) node->children[ch] = new Trie(); node = node->children[ch]; } node->isEnd = true; } bool search(string word) { Trie* node = this->searchPrefix(word); return node != nullptr && node->isEnd; } bool startsWith(string prefix) { return this->searchPrefix(prefix) != nullptr; } };
测试代码
int main() { Trie trie; trie.insert("string"); trie.insert("stdmain"); cout << trie.search("unfea") <<endl; cout << trie.search("stdmain") << endl; cout << trie.startsWith("tf") << endl; cout << trie.startsWith("st"); return 0; }
本文作者:YaosGHC
本文链接:https://www.cnblogs.com/yaocy/p/16975729.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步