1.容器存敏感词
// 创建敏感词过滤器对象
vector<string> sensitiveWords = {"ffuck","fuck","fuck"};
2.Tire树结构定义
class TrieNode {
public:
bool is_end; // 是否到达字符串末尾
unordered_map<char, TrieNode*> next; // 子节点集合
TrieNode() : is_end(false) {}
};
3.敏感词过滤类
包括addword()添加敏感词的方法,过滤文本中敏感词的方法并且将敏感词该为*******。
class TrieFilter {
private:
TrieNode* root; // Trie树根节点
public:
TrieFilter(const vector<string>& sensitiveWords) {
root = new TrieNode(); // 创建Trie树根节点
for (const auto& word : sensitiveWords)
addWord(word); // 将敏感词添加到Trie树中s
}
~TrieFilter() {
deleteNode(root); // 释放Trie树节点内存
}
// 添加敏感词到Trie树中
void addWord(const string& word) {
TrieNode* node = root;
// 从根节点开始遍历Trie树
//添加敏感词到树
for (char c : word) {
if (node->next.find(c) == node->next.end()) {
// 如果当前节点不存在字符c的子节点,创建新的子节点
node->next[c] = new TrieNode();
}
node = node->next[c];
// 更新节点为字符c的子节点
}
node->is_end = true;
// 将最后一个节点标记为字符串末尾
}
// 过滤文本中的敏感词
string filter(const string& input) {
string filteredInput = input;
// 将输入文本复制到一个新的字符串中,用于修改过滤后的文本
for (int i = 0; i < input.size(); ++i) {
TrieNode* node = root;
// 从根节点开始遍历Trie树
int wordStartIndex = -1;
// 敏感词的起始索引,默认值为-1
// 从当前位置开始匹配敏感词
for (int j = i; j < input.size(); ++j) {
if (node->next.find(input[j]) == node->next.end())
break; // 如果当前节点不存在字符c的子节点,结束匹配
node = node->next[input[j]];
// 更新节点为字符c的子节点
if (node->is_end)
wordStartIndex = j;
// 如果当前节点是字符串末尾,更新敏感词的起始索引
}
// 如果匹配到敏感词,将对应位置的字符替换为星号(*)
if (wordStartIndex != -1) {
int wordLength = wordStartIndex - i + 1;
// 计算敏感词的长度
for (int j = 0; j < wordLength; ++j)
filteredInput[i + j] = '*';
// 将敏感词位置的字符替换为星号(*),实现过滤
i = wordStartIndex; // 跳过已匹配的敏感词
}
}
return filteredInput;
// 返回过滤后的文本
}
private:
// 递归释放Trie树节点内存
void deleteNode(TrieNode* node) {
if (!node)
return;
for (auto it = node->next.begin(); it != node->next.end(); ++it)
deleteNode(it->second);
delete node;
}
};
5.完整运行代码
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
using namespace std;
class TrieNode {
public:
bool is_end; // 是否到达字符串末尾
unordered_map<char, TrieNode*> next; // 子节点集合
TrieNode() : is_end(false) {}
};
class TrieFilter {
private:
TrieNode* root; // Trie树根节点
public:
TrieFilter(const vector<string>& sensitiveWords) {
root = new TrieNode(); // 创建Trie树根节点
for (const auto& word : sensitiveWords)
addWord(word); // 将敏感词添加到Trie树中s
}
~TrieFilter() {
deleteNode(root); // 释放Trie树节点内存
}
// 添加敏感词到Trie树中
void addWord(const string& word) {
TrieNode* node = root;
// 从根节点开始遍历Trie树
//添加敏感词到树
for (char c : word) {
if (node->next.find(c) == node->next.end()) {
// 如果当前节点不存在字符c的子节点,创建新的子节点
node->next[c] = new TrieNode();
}
node = node->next[c];
// 更新节点为字符c的子节点
}
node->is_end = true;
// 将最后一个节点标记为字符串末尾
}
// 过滤文本中的敏感词
string filter(const string& input) {
string filteredInput = input;
// 将输入文本复制到一个新的字符串中,用于修改过滤后的文本
for (int i = 0; i < input.size(); ++i) {
TrieNode* node = root;
// 从根节点开始遍历Trie树
int wordStartIndex = -1;
// 敏感词的起始索引,默认值为-1
// 从当前位置开始匹配敏感词
for (int j = i; j < input.size(); ++j) {
if (node->next.find(input[j]) == node->next.end())
break; // 如果当前节点不存在字符c的子节点,结束匹配
node = node->next[input[j]];
// 更新节点为字符c的子节点
if (node->is_end)
wordStartIndex = j;
// 如果当前节点是字符串末尾,更新敏感词的起始索引
}
// 如果匹配到敏感词,将对应位置的字符替换为星号(*)
if (wordStartIndex != -1) {
int wordLength = wordStartIndex - i + 1;
// 计算敏感词的长度
for (int j = 0; j < wordLength; ++j)
filteredInput[i + j] = '*';
// 将敏感词位置的字符替换为星号(*),实现过滤
i = wordStartIndex; // 跳过已匹配的敏感词
}
}
return filteredInput;
// 返回过滤后的文本
}
private:
// 递归释放Trie树节点内存
void deleteNode(TrieNode* node) {
if (!node)
return;
for (auto it = node->next.begin(); it != node->next.end(); ++it)
deleteNode(it->second);
delete node;
}
};
int main() {
// 创建敏感词过滤器对象
vector<string> sensitiveWords = {"ffuck","fuck","fuck"};
TrieFilter filter(sensitiveWords);
// 从用户输入中读取待检查的文本
string input;
cout << "请输入你的词汇: ";
getline(cin, input);
// 进行敏感词过滤
string filteredInput = filter.filter(input);
// 输出过滤结果
cout << "DFA过滤结果: " << filteredInput << endl;
return 0;
};
6.该程序还可以进行进一步的优化,当出现多个相同的单词如fuck,ffuck,该敏感树会创建多余的空间。