应用实例:敏感词过滤 + 自动补全
本系列的匹配算法支撑着日常产品里的两类功能:一遍扫出大量关键词(敏感词 / 风控 / DPI),和输入几个字便弹出候选(搜索框 / 输入法补全)。下面两个 demo 分别由 Aho-Corasick 自动机和 Trie 前缀树驱动。
1 · 敏感词过滤:一遍扫出所有命中(Aho-Corasick)
要在一段文字里同时查找成百上千个关键词,逐个用 KMP 扫描效率太低。Aho-Corasick 把所有关键词建成一棵带 fail 指针的 Trie,文本只扫一遍就能给出全部命中,复杂度 ,和关键词数量几乎无关。改文字或词表,实时高亮:
fail 指针是关键:在某个词上匹配失败时,不用把文本指针退回去重扫,而是顺着 fail 跳到「最长的、仍可能接上的另一个词的位置」继续——本质就是 KMP 的 next 数组推广到多个模式。详见 Aho-Corasick 一页。
2 · 自动补全:按前缀给出候选(Trie 前缀树)
搜索框 / 输入法 / IDE 的补全:把词典建成 Trie,公共前缀共用一条路径。输入前缀就顺着走到那个节点,它子树下的所有词就是候选——与词典总量无关,只与前缀长度和候选数有关。输入前缀查看效果:
3 · 同一批算法的其他应用场景
- 代码 / 全文搜索:
ripgrep/ grep 用 Boyer-Moore 大步跳过;Elasticsearch / Lucene 倒排索引里的 term 匹配与前缀查询(Trie / FST)。 - 生物信息 / 压缩:DNA 序列比对的后缀数组 / FM-index(BWA、Bowtie 基因比对器);
bzip2的 BWT、长文本全文索引都建在后缀结构上。 - 拼写纠错 / 模糊搜索:「你是不是想搜…」靠编辑距离 + BK-tree:在词典里找与输入差几步以内的词,用三角不等式剪掉大片分支。
- 防火墙 / DLP / 反垃圾:Aho-Corasick 一遍扫出成千上万条特征 / 敏感词;Snort、Suricata 的多模式特征匹配同款。