敏感词过滤

敏感词过滤&防沉迷,基本所有上线系统都会用的基础功能吧,网上挺多代码的,也很多种方式,看的有点绕
写了个自己感觉比较干净清楚的,结构也比较简单,记录一下
insert 和 censor(审查、检查)都是递归,效率还好,win release版本5700的样本,length = 1000的censor_str 大概0.2ms
支持比如敏感词库有 ab  abcd  检查 abc 这种 (网上下下来的试了几个好像都不支持,觉得这种还是有必要的)
struct mgc_node 
{
    std::unordered_map<char, mgc_node> _node;   // 递归节点
    bool _end;                        // 整词结尾

    mgc_node()
        :_end(false)
    {

    }

    void censor(string& source, size_t& pos, size_t& cnt, size_t& last_cnt)
    {
        auto it = source.begin() + pos;
        if (it == source.end())
            return ;

        auto subit = _node.find(*it);
        if (subit == _node.end())
            return ;

        cnt += 1; // 匹配到一个

        if (subit->second._end)  // 是结尾
            last_cnt = cnt;

        pos += 1;

        subit->second.censor(source, pos, cnt, last_cnt);
        return;
    }
};

class mgc
{
private:
    mgc_node _root;
public:
    bool insert(const string& source)
    {
        if (source.empty())
            return true;

        mgc_node* _curr = &_root;

        size_t len = source.length();
        for (size_t i = 0; i < len; ++i)
        {
            mgc_node& _next = _curr->_node[source[i]];

            _curr = &_next;

            if (i + 1 == len)
                _curr->_end = true;
        }
        return true;
    }

    std::string censor(const string& source)
    {
        std::stringstream ss;

        int lenght = source.size();
        for (int i = 0; i < lenght; )
        {
            string substring = source.substr(i);

            size_t pos = 0;        // 递归使用,字符串开始匹配的位置
            size_t cnt = 0;        // 递归使用,匹配到的字符数
            size_t last_cnt = 0;   // 递归&返回使用,整词的字符数
            _root.censor(substring, pos, cnt, last_cnt);

            if (last_cnt > 0)
            {
                ss << "*";
                i += last_cnt;
            }
            else
            {
                ss << source.at(i); 
                i += 1;
            }
        }
        return std::move(ss.str());
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值