码迷,mamicode.com
首页 > 其他好文 > 详细

AC自动机

时间:2018-09-20 01:08:51      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:fail   lse   toc   string   private   rar   new   pre   span   

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自动机

标签:fail   lse   toc   string   private   rar   new   pre   span   

原文地址:https://www.cnblogs.com/xinyi-blog/p/9678284.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!