zoukankan      html  css  js  c++  java
  • AC自动机的一些处理方法

    一些经典的问题:
    1. 求各个模式串在文本串中出现了几次:

      方法: 在AC自动机上先跑一边文本串,记录一下每个点被经过的次数,那么单词被经过的次数就是他的结尾在fail树中的子树的权值和

    2. 找是否有一个匹配不上匹配串的环:

      方法: 把所有能匹配上匹配串的节点匹配记录下来,dfs从跟开始走所有我可以走的点,如果我走到了一个之前走过的点就说明出环了

      实现: 一边调用fail一边更新当前点是否能走,因为fail记录的是前缀等于后缀,后缀深度一定比前缀大,所以fail一定在之前就走过了

    3. (n)个串总共出现(m)次的最短长度

      方法: 求两两单词结尾之间的最短距离,初始矩阵(a_{i,j})表示结尾(i)和结尾(j)之间不经过其他结尾的最短距离,矩阵快速幂(m-1)

      更新成(a_{i,j})表示结尾(i)到结尾(j)之间经过其他(m-2)个结尾的最小距离,现在总共经过了(m)个单词结尾,再加上第一个单词的长度,就是最短长度,一共(nm)种情况取最小的一种

    4. 每次删掉文本串中的最早出现的模式串,剩下的字符继续拼在一起

      方法: 跑AC自动机,模拟栈,发现匹配到一个单词,把属于这个单词的字符全部弹出,继续从之前匹配的位置继续往下找

    注意问题:
    1. 在fail树上拓排的时候在更新fail指针的时候进行,如:
          fail[trie[root][i]] = trie[fail[root]][i];
          du[trie[fail[root]][i]] ++;
    
    1. 看当前字符是否能匹配上匹配串是在调用fail的时候进行,如:
          trie[root][i] = trie[fail[root]][i];
          vis[trie[root][i]] |= vis[trie[fail[root]][i]];
    
  • 相关阅读:
    mini2440 UBoot启动过程完全分析
    Linux Shell常用命令学习(1)
    S3C6410启动模式介绍
    漫画与新媒体的传播思考
    注册表修改启动项
    邮件主题是乱码的原因gbk 在utf8 显示问题
    移动 电话费 套餐
    java 异常的问题讨论
    领结的打法
    c# 字符之间的转换
  • 原文地址:https://www.cnblogs.com/little-uu/p/14051581.html
Copyright © 2011-2022 走看看