zoukankan      html  css  js  c++  java
  • ac自动机,不详细,好理解

    详细的解答这里不再赘述,推荐两篇博文,

    https://www.cnblogs.com/hyfhaha/p/10802604.html;

    https://blog.csdn.net/wyxeainn/article/details/77430218?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6;

    这里略微分析一下我对前缀数组的认识和性质 

    //定理 1:对于每一条树链如果fial[level1[k1]]=fial[level2[k2]],k1<k2,则存在0~k1,fial[level[i]]=fial[level2[k2-k1+i]]总成立
     //性质2:fail路径直达定理,如果fail[level]指向的是一个本来不存在的地址,trie[][i]存在可能最大的地址;
    //匹配失败:如果文章匹配到某一条树链的level[t],下一个要查询的是index+'a,然而trie[level[t]][index]不存在我们就定义失败,扫描的指针指向fail
    // fail 指针的作用:当前的树链是否可能是别的树链答案,已经是别的树链的答案。我们通过fail遍历所有以当前字母结尾的前缀中是否有答案;

     1 #include<iostream>
     2 #include<string>
     3 #include<queue>
     4 #include<cstring>
     5 using namespace std;
     6 const int MAX_=1e5;
     7 int trie[MAX_][26]={0};
     8 int wordti[MAX_]={0};//功能数组; 
     9 int fail[MAX_]={0};
    10 int cnt=0;
    11 void insert(string x)
    12 {
    13     int len=x.size(),p=0;
    14     for(int i=0;i<len;i++)
    15     {
    16         int index=x[i]-'a';
    17         if(trie[p][index]!=0)
    18             trie[p][index]=++cnt;
    19         p=trie[p][index];
    20     }
    21     wordti[p]++;
    22  } 
    23  //定理 1:对于每一条树链如果fial[level1[k1]]=fial[level2[k2]],k1<k2,则存在0~k1,fial[level[i]]=fial[level2[k2-k1+i]]总成立
    24  //性质2:fail路径直达定理,如果fail[level]指向的是一个本来不存在的地址,trie[][i]存在可能最大的地址; 
    25 //匹配失败:如果文章匹配到某一条树链的level[t],下一个要查询的是index+'a,然而trie[level[t]][index]不存在我们就定义失败,扫描的指针指向fail 
    26 // fail 指针的作用:当前的树链是否可能是别的树链答案,已经是别的树链的答案。我们通过fail遍历所有以当前字母结尾的前缀中是否有答案; 
    27  void getfail()
    28  {
    29      queue<int >que;
    30      for(int i=0;i<26;i++)
    31          if(trie[0][i]!=0){
    32              fail[trie[0][i]]=0;
    33              que.push(trie[0][i]);
    34         } 
    35     while(!que.empty()){
    36         int now=que.front();
    37         que.pop();
    38         for(int i=0;i<26;i++){
    39             if(trie[now][i]!=0){
    40                 fail[trie[now][i]]=trie[fail[now]][i];//祖先继承法;特征我们数通过记忆化搜索,或者等于它已经记录的数据实现的 
    41                 que.push(trie[now][i]); 
    42             }
    43             else
    44                 trie[now][i]=trie[fail[now]][i];//我们只要研究如果当前节点存在,就往下搜索,如果这个指针不存在,我们通过fail直接到达可行的下表 
    45         }
    46     }
    47  }
    48  
    49 void query(char *s)
    50 {
    51     int u=0,len=strlen(s);
    52     for(int i=0;i<len;i++){
    53         int index=s[i]-'a';
    54         u=trie[u][index]; 
    55         //功能区 ,寻找以当前字母结尾是否存在已经匹配成功的模式窜 
    56         int k=u;
    57         while(k>0){
    58             if(wordti[k]>0) ans++;
    59             k=fail[k];
    60         } 
    61     } 
    62 } 
  • 相关阅读:
    JVM实战---类加载的过程
    MobaXterm:远程终端登录软件封神选手
    Linux内核实战(二)- 操作系统概览
    Linux再学习(一)-学习路线规划
    Flink实战(八)
    Docker实战之Redis-Cluster集群
    通过乐观锁解决库存超卖的问题
    Docker实战之MySQL主从复制
    JVM类加载器是否可以加载自定义的String
    设计模式--单例
  • 原文地址:https://www.cnblogs.com/hjw201983290498/p/12783568.html
Copyright © 2011-2022 走看看