AC 自动机

AC自动机

AC自动机是一个经典的多模式串匹配算法,它可以实现对主串的一次扫描来匹配多个模式串的功能。
实现AC自动机就是在Trie树的基础上加上了类似KMP的next数组。

class ACNode{
    public int data;
    public ACNode[] children = new ACNode[26];
    public boolean isEndingChar = false;
    public int length = -1;
    public ACNode fail;

    public ACNode(char data) {
        this.data = data;
    }
}

AC自动机的构造分成两步:

  1. 构造Trie树
  2. 在Trie树的基础上构建fail指针(相当于KMP的next数组)
    Trie树的构造可以参考Trie树;
    下面是fail指针的构建
public class AC {
    private ACNode root = new ACNode('/');
    public void buildFailurePointer(){
        Queue<ACNode> queue = new LinkedList<ACNode>();
        root.fail = null;
        queue.add(root);
        while(!queue.isEmpty()){
            ACNode p = queue.remove();
            for(int i = 0; i < 26; i++){
                ACNode pc = p.children[i];
                if(p.children[i] == null){
                    continue;
                }
                if(p == root){
                    pc.fail = root;
                }
                else{
                    ACNode q = p.fail;
                    while(q != null){
                        ACNode qc = q.children[pc.data - 'a'];
                        if(qc != null){
                            pc.fail = qc;
                            break;
                        }
                        q = q.fail;
                    }
                    if(q == null){
                        pc.fail = root;
                    }
                }
                queue.add(pc);
            }
        }
    }
    public void match(char[] text){
        int n = text.length;
        ACNode p = root;
        for(int i = 0; i < n; i++){
            int index = text[i] - 'a';
            while(p.children[index] == null && p != root){
                p = p.fail;
            }
            p = p.children[index];
            if(p == null){
                p = root;
            }
            ACNode temp = p;
            while(temp != root){
                if(temp.isEndingChar){
                    int pos = i - temp.length + 1;
                    System.out.println("matched from index " + pos + "; length " +temp.length);
                }
                temp = temp.fail;
            }
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 参考博文:AC自动机算法详解 (转载) (原文作者:DarkRaven,原文的链接失效了)图片来源:AC自动机算...
    jenye_阅读 4,727评论 2 4
  • AC自动机(Aho-Corasick\ automaton),可以解决多模板串匹配的问题。可以理解为可以一次性匹配...
    An_Account阅读 489评论 0 1
  • 文不达意,口齿不清,思想混乱,令人喷饭。(估计只有我自己才能看懂我在说什么)简书没有mathjax公式没法愉快显示...
    njzwj阅读 1,197评论 1 2
  • 预备知识 Trie(字典树)KMP字符串匹配算法 AC自动机求解问题的类型 一句话概括就是:多模匹配。KMP求解的...
    ZJL_OIJR阅读 1,034评论 0 1
  • “睽”,乖异。看卦画,斜眼看人,翻白眼。古人看见了弓和箭。 睽,目不相视为睽,因此解为乖异,即同居异志、同床异梦之...
    童年的流星阅读 1,164评论 0 6