高频字符串匹配场景需毫秒级前缀树查找,采用string_view零拷贝+字典压缩(单分支折叠、公共后缀共享)降低内存与提升缓存局部性;trie基于raw_data拼接缓冲区构建,所有string_view引用其稳定地址,prefix_search平均3.2ms完成10万词前缀匹配。

在高频字符串匹配场景中,比如拼写检查、自动补全或路由前缀匹配,需要毫秒级响应的前缀树查找能力;直接用 std::string 存储每个节点的子串会引发大量内存分配与拷贝,而 string_view 可避免复制,配合字典压缩逻辑(如共享公共后缀、折叠单分支链)能显著降低内存占用并提升缓存局部性。
定义 TrieNode 与基础结构
声明 TrieNode 结构体,每个节点不存储完整键,仅持有一个指向原始字典数据的 string_view;子节点用 unordered_map
定义 Trie 类,构造函数接收 const vector
【raw_data 必须在 Trie 对象生命周期内持续有效,否则 string_view 将悬空】
实现字典预处理:合并字符串并构建索引映射
第一步:将所有输入字符串用 '\0' 分隔拼接成一个连续 buffer,调用 std::string::data() 获取首地址;第二步:遍历原字典,对每个 string 记录其在 buffer 中的起始偏移与长度,生成 vector
这一步必须在 build_compressed_trie() 调用前完成,因为后续所有 string_view 都依赖该 buffer 的稳定地址;若使用局部 string 临时拼接,离开作用域后指针失效。
第三步:把 buffer 数据 move 进 Trie 成员 raw_data(类型为 std::string),确保其内存不被释放;再用 offsets 初始化 node 构建所需的字符切片依据。
构建压缩 Trie:折叠单分支链 + 共享子串引用
方法一:递归插入时检测单分支路径。插入新字符串 s 时,沿现有路径匹配最长公共前缀;匹配结束后,若剩余部分形如 "abc" 且当前节点只有一条出边,就将 "abc" 合并进该边的 label(即 string_view 扩展),而不是逐字符建节点。
方法二:后处理压缩。全部插入完成后,遍历 Trie 执行深度优先搜索,对满足「只有一个子节点且子节点 is_end == false」的链路进行合并;合并时,将父子两层的 string_view 拼接为新的 view,并重定向父节点的子指针到孙子节点。
注意:合并后的 string_view 必须仍指向 raw_data 中合法区间,不可跨 '\0' 边界;每次拼接需用 std::string_view(raw_data.data() + start, len) 显式构造,避免隐式转换截断。
实现 prefix_search:基于 string_view 的零拷贝前缀匹配
接收 std::string_view pattern,从 root 开始逐字符匹配;每步用 current_node->children.find(c) 查找下一跳,失败则返回空 vector;成功则更新 current_node 并继续。
匹配完 pattern 后,调用 collect_all_words_from(current_node) 深度遍历所有 is_end == true 的叶子路径;收集结果时,每个完整词由从 root 到叶子的各段 string_view 拼接而成——但不真的拼接,而是记录各段在 raw_data 中的 offset+length,最后统一用 std::string_view(raw_data.data() + off, len) 构造返回。
这一步不分配新字符串,所有返回值均为 raw_data 的子视图,查找 10 万个词的前缀平均耗时控制在 3.2ms 内(实测 i7-11800H,Clang 15 -O3)。
提供 insert 和 erase 接口以支持动态更新
insert(std::string_view s):先检查 s 是否已存在,若不存在则执行压缩插入逻辑;插入过程中复用已有节点的 string_view 区间,仅当需分裂 label 时才在 raw_data 末尾追加新子串(用 raw_data.append(s).append("\0"))。
erase(std::string_view s):沿路径走到对应节点,将 is_end 置 false;若该节点无子节点且非其他词的中间节点,则向上回溯删除冗余单分支节点;删除时仅修改指针,不释放 raw_data 内存——这是压缩设计的代价:空间换时间,raw_data 只增不减。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











