AC自动机

Posted xinyi-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC自动机相关的知识,希望对你有一定的参考价值。

import java.util.*;

public class Main{
    public static void main(String[] args){
        String S = "yasherhs";
        String[] words = {"say","she","shr","he","her","hs"};
        System.out.println(numMatchingSubseq(S,words));
    }
    public static int numMatchingSubseq(String S, String[] words) {
        int len = words.length;
        Node root = new Node(0);
        for(int i=0;i<len;i++){
            insert(root,words[i]);
        }
        adjustFail(root);
        char[] c = S.toCharArray();
        len = c.length;
        int result = 0;
        Node temp = root;
        for(int i=0;i<len;){
            int num = c[i]-‘a‘;
            if(temp==root && temp.child[num]==null){
                i++;
                continue;
            }
            if(temp.child[num]!=null){
                result += temp.child[num].count;
                temp = temp.child[num];
                i++;
            }else{
                temp = temp.fail;
                result+= temp.count;
            }
        }
        return result;
    }
    private static void insert(Node root,String s){
        int len = s.length();
        char[] c = s.toCharArray();
        Node temp = root;
        for(int i=0;i<len;i++){
            if(temp.child[c[i]-‘a‘]==null){
                temp.child[c[i]-‘a‘] = new Node(c[i]-‘a‘);
                temp.child[c[i]-‘a‘].parent = temp;
            }
            temp = temp.child[c[i]-‘a‘];
        }
        temp.count++;
    }
    private static void adjustFail(Node root){
        Queue<Node> queue = new LinkedList<>();
        for(int i=0;i<26;i++){
            if(root.child[i]==null){
                continue;
            }
            root.child[i].fail = root;
            queue.add(root.child[i]);
        }
        while(queue.size()!=0){
            Node node = queue.poll();
            for(int i=0;i<26;i++){
                if(node.child[i]!=null){
                    node.child[i].fail = root;
                    Node fail = node.fail;
                    while(fail!=null){
                        if(fail.child[node.child[i].value]!=null){
                            node.child[i].fail = fail.child[node.child[i].value];
                            break;
                        }else{
                            fail = fail.fail;
                        }
                    }
                    queue.add(node.child[i]);
                }
            }
        }
    }
    private static void print(Node root){
        Node temp = root;
        for(int i=0;i<26;i++){
            if(root.child[i]!=null){
                System.out.print(i+"&"+root.child[i].fail.value+" ");
                print(root.child[i]);
            }
        }
        System.out.println();
    }
}
class Node{
    Node[] child;
    Node parent;
    Node fail;
    int value;
    int count;
    public Node(int value){
        this.count = 0;
        this.child = new Node[26];
        this.value = value;
    }
}

 

以上是关于AC自动机的主要内容,如果未能解决你的问题,请参考以下文章

POJ3691DNA repair(AC自动机,DP)

HDU4057 Rescue the Rabbit(AC自动机+状压DP)

Codeforces 86C Genetic engineering(AC自动机+DP)

POJ1699 Best Sequence(AC自动机+状压DP)

POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂

HDU2457 DNA repair(AC自动机+DP)