基于 Trie 实现敏感词过滤

简介: 本文章利用 Trie 数据结构来过滤敏感词

加载外部文件

publicvoidinit() {
try (
InputStreamis=this.getClass().getClassLoader().getResourceAsStream("sensitive-words.txt");
BufferedReaderreader=newBufferedReader(newInputStreamReader(is));) {
Stringkeyword;
while ((keyword=reader.readLine()) !=null) {
// 添加到前缀树this.addKeyword(keyword);
        }
    } catch (IOExceptione) {
logger.error("加载敏感词文件失败: "+e.getMessage());
    }
    }

定义 Trie

privateclassTrieNode {
// 关键词结束标识privatebooleanisKeywordEnd=false;
// 子节点(key是下级字符,value是下级节点)privateMap<Character, TrieNode>subNodes=newHashMap<>();
publicbooleanisKeywordEnd() {
returnisKeywordEnd;
    }
publicvoidsetKeywordEnd(booleankeywordEnd) {
isKeywordEnd=keywordEnd;
    }
// 添加子节点publicvoidaddSubNode(Characterc, TrieNodenode) {
subNodes.put(c, node);
    }
// 获取子节点publicTrieNodegetSubNode(Characterc) {
returnsubNodes.get(c);
    }
}

将一个敏感词添加到前缀树中

privatevoidaddKeyword(TrieNoderootNode, Stringkeyword) {
TrieNodetempNode=rootNode;
for (inti=0; i<keyword.length(); i++) {
charc=keyword.charAt(i);
TrieNodesubNode=tempNode.getSubNode(c);
if (subNode==null) {
// 初始化子节点subNode=newTrieNode();
tempNode.addSubNode(c, subNode);
        }
// 指向子节点,进入下一轮循环tempNode=subNode;
// 设置结束标识if (i==keyword.length() -1) {
tempNode.setKeywordEnd(true);
        }
    }
}

过滤敏感词

publicStringfilter(Stringtext) {
if (StringUtils.isBlank(text)) {
returnnull;
    }
// 指针1TrieNodetempNode=rootNode;
// 指针2intbegin=0;
// 指针3intposition=0;
// 结果StringBuildersb=newStringBuilder();
while (position<text.length()) {
charc=text.charAt(position);
// 跳过符号if (isSymbol(c)) {
// 若指针1处于根节点,将此符号计入结果,让指针2向下走一步if (tempNode==rootNode) {
sb.append(c);
begin++;
            }
// 无论符号在开头或中间,指针3都向下走一步position++;
continue;
        }
// 检查下级节点tempNode=tempNode.getSubNode(c);
if (tempNode==null) {
// 以begin开头的字符串不是敏感词sb.append(text.charAt(begin));
// 进入下一个位置position=++begin;
// 重新指向根节点tempNode=rootNode;
        } elseif (tempNode.isKeywordEnd()) {
// 发现敏感词,将begin~position字符串替换掉sb.append("****");
// 进入下一个位置begin=++position;
// 重新指向根节点tempNode=rootNode;
        } else {
// 检查下一个字符position++;
        }
    }
// 将最后一批字符计入结果sb.append(text.substring(begin));
returnsb.toString();
}
目录
相关文章
|
2月前
|
搜索推荐
前缀树Trie
前缀树Trie
|
2月前
|
存储 C++
leetcode-208:实现 Trie (前缀树/字典树)
leetcode-208:实现 Trie (前缀树/字典树)
30 0
|
2月前
|
NoSQL 容器 消息中间件
字典树 (Trie)
字典树 (Trie)
|
8月前
|
存储 Python
字典树(Trie,
字典树(Trie,也称为前缀树或单词查找树)是一种用于存储字符串的树形数据结构。它是一种特殊的多叉树,其中每个节点都包含一个字符和一个指向其子节点的指针数组。字典树的主要作用是用于快速查找字符串和处理字符串的前缀。
43 6
|
2月前
|
存储 算法 vr&ar
☆打卡算法☆LeetCode 208. 实现 Trie (前缀树) 算法解析
☆打卡算法☆LeetCode 208. 实现 Trie (前缀树) 算法解析
|
12月前
|
搜索推荐 数据格式
Trie字典树
Trie字典树
74 0
Trie字典树
|
11月前
|
存储 Java
Java数据结构之第十五章、Trie(前缀树/单词查找树)
1.前缀树的概念:前缀树又叫字典树或单词查找树(高效的存储和查找字符串集合的数据结构)。2.3.存储形式:存储的字符串可能:全是 小写字母 或全是 大写字母 或全是 数字 或全是 0和1。它是一棵,每个代表一个,从。字典树的根节点不包含字符,每个子节点代表一个字符,从根节点到任意一个节点所经过的路径上的字符连接起来即为该节点所代表的字符串。每个节点可以存储一个或多个字符串,通常使用一个标志来标记一个节点代表的字符串是否存在。当需要在一组字符串中查找某个字符串时,可以利用字典树来实现高效的查找操作。
53 0
|
11月前
|
搜索推荐
字典树 trie
字典树 trie
37 0
理解前缀树
理解前缀树
42 0
|
存储
前缀树
Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
63 0
前缀树