zoukankan      html  css  js  c++  java
  • 敏感词过滤 AC自动机

    复杂度n^2 ,没想出来怎么优化,‘*’赋值可以差分写,不过不减复杂度

    #include <queue>
    #include <cstdlib>
    #include <cmath>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn =  2*1e3+9;
    typedef pair<int,int> pii;
    
    int trie[maxn][26]; 
    int cntword[maxn];  
    int fail[maxn];     
    int cnt = 0;
    int len[maxn];
    
    void insertWords(string s){
        int root = 0;
        for(int i=0;i<(int)s.size();i++){
            int next = s[i] - 'a';
            if(!trie[root][next])
                {
                    trie[root][next] = ++cnt;
                    len[cnt]=len[root]+1;
                }
            root = trie[root][next];
        }
        cntword[root]++;      
    }
    
    void getFail(){
        queue <int>q;
        for(int i=0;i<26;i++){     
            if(trie[0][i]){
                fail[trie[0][i]] = 0;
                q.push(trie[0][i]);
            }
        }
        while(!q.empty()){
            int now = q.front();
            q.pop();
    
            for(int i=0;i<26;i++){  
                if(trie[now][i]){
                    fail[trie[now][i]] = trie[fail[now]][i];
                    q.push(trie[now][i]);
                }
                else
                trie[now][i] = trie[fail[now]][i];
            }
        }
    }
    
    std::vector<pii> v;
    void query(string &s){
        int now = 0;
        for(int i=0;i<(int)s.size();i++){    
            now = trie[now][s[i]-'a']; 
            for(int j=now;j;j=fail[j]){
              
                if(cntword[j])
                {
                    for(int ss=i-len[j]+1;ss<=i;ss++)
                {       
                        s[ss]='*';
                }
               // v.push({i-len[j]+1,i});
                break;
                }
            }
        }
        /*int p[maxn];
        int vis[maxn];
        memset(p,0,sizeof(p));
        memset(vis,0,sizeof(vis));
        for(pii x:v)
        {
            int 
        }    */
        
    }
    
    
    int main() {
        int n;
        string s;
        cin >> n;
        for(int i=0;i<n;i++){
            cin >> s ;
            insertWords(s);
        }
        fail[0] = 0;
        getFail();
        cin >> s ;
        query(s);
        cout<<s<<endl;
        //cout << query(s) << endl;
        return 0;
    }
  • 相关阅读:
    Linux下卸载openjdk,安装jdk
    dom4j移除节点不成功
    运费模版源码(.net)
    电子商城系统运费模板设计
    【转】js判断手机访问网页
    nopcommerce之一(结构分析)
    js阻止提交表单(post)
    s1=s1+1与s1+=1的区别
    .net中从GridView中导出数据到excel(详细)
    分布式事务中常见的三种解决方案
  • 原文地址:https://www.cnblogs.com/acmLLF/p/14757122.html
Copyright © 2011-2022 走看看