数据结构-前缀树(Trie)

211. 添加与搜索单词 - 数据结构设计

实现代码如下所示:

cpp 复制代码
#include <bits/stdc++.h>  // 包含标准库所有头文件
using namespace std;      // 使用标准命名空间

class WordDictionary {
public:
    WordDictionary() = default;  // 默认构造函数,root已在声明处初始化

    // 添加单词到字典树
    void addWord(const string& word) {
        TrieNode* node = root;  // 从根节点开始遍历
        
        for (char ch : word) {  // 遍历单词的每个字符
            // 如果当前字符的子节点不存在,则创建新节点
            if (node->children.find(ch) == node->children.end()) {
                node->children[ch] = new TrieNode();
            }
            node = node->children[ch];  // 移动到子节点继续
        }
        node->isEnd = true;  // 标记单词结束位置
    }

    // 搜索单词(支持通配符'.')
    bool search(const string& word) {
        // 从位置0和根节点开始递归搜索
        return searchInNode(word, 0, root);
    }

private:
    // 字典树节点结构
    struct TrieNode {
        unordered_map<char, TrieNode*> children;  // 使用哈希表存储子节点,节省空间
        bool isEnd = false;  // 标记是否为某个单词的结尾
    };

    TrieNode* root = new TrieNode();  // 字典树的根节点

    // 递归搜索辅助函数
    bool searchInNode(const string& word, int pos, TrieNode* node) {
        if (!node) return false;  // 节点不存在,匹配失败
        
        // 已经处理完整个单词,检查当前节点是否为单词结尾
        if (pos == word.size()) return node->isEnd;

        char ch = word[pos];  // 获取当前位置的字符
        
        if (ch == '.') {
            // 通配符:需要尝试所有可能的子节点
            for (auto& [key, child] : node->children) {
                // 对每个子节点递归搜索剩余部分
                if (searchInNode(word, pos + 1, child)) {
                    return true;  // 只要有一个分支匹配就成功
                }
            }
            return false;  // 所有分支都失败
        } else {
            // 普通字符:查找对应的子节点
            auto it = node->children.find(ch);
            if (it == node->children.end()) return false;  // 字符不存在,匹配失败
            
            // 继续匹配下一个字符
            return searchInNode(word, pos + 1, it->second);
        }
    }
};


int main() {
    WordDictionary wordDictionary;
    wordDictionary.addWord("bad");
    wordDictionary.addWord("dad");
    wordDictionary.addWord("mad");

    cout << boolalpha;
    cout << wordDictionary.search("pad") << endl; // false
    cout << wordDictionary.search("bad") << endl; // true
    cout << wordDictionary.search(".ad") << endl; // true
    cout << wordDictionary.search("b..") << endl; // true
    cout << wordDictionary.search(".a..") << endl; // false (长度不匹配自动剪枝)

    return 0;
}
相关推荐
“AI国潮设计-小江”几秒前
《【AIGC实战】Python+SDXL批量生成“猫咪英歌舞蛋挞”IP,附保持角色一致性的代码逻辑》
开发语言·人工智能·python·prompt·aigc
坤坤子吖16 分钟前
Linux 线程概念与控制——线程创建、退出与等待
linux·开发语言·c++·笔记·学习
薛一半17 分钟前
Redux实战:组件状态管理全解析
开发语言·前端·javascript·react.js
weixin_3077791321 分钟前
C++代码实现MATLAB中的fitnlm函数功能
开发语言·c++·算法·matlab
白帽攻防录9 小时前
SRC 挖洞:PostScript 打印机驱动双 RCE,打印服务器怎么变成内网跳板
开发语言·网络安全·php·内网安全
十年Java程序媛9 小时前
Java枚举Enum完整教程|替代静态常量,开发与面试要点
java·开发语言·spring boot·后端·面试
2603_965148119 小时前
电商选品调研:通过关键词搜索API获取市场热销商品,结合商品详情API分析竞品卖点与定价
开发语言·数据库·人工智能·python·信息可视化
xixiaoyunya10 小时前
Python 异步编程入门:用 asyncio 轻松实现并发任务
开发语言·python·php
学逆向的10 小时前
C 循环结构的执行效率分析
c语言·开发语言·数据结构·网络安全