Tire树继续敏感词的过滤,C++

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,该敏感树会创建多余的空间。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值