[置顶] AC自动机模板(c++版和java版)

        这是我第一次写博客,可能整理的不好,请大家见谅。

        先发一些我最近在刷的AC自动机的题,模版题我就不发了。。初学的话,可以看一下

AC自动机算法 - 飘过的小牛 - 博客频道 - CSDN.NET

的博客。

        另外贴一个模版题的代码吧

        hdu2222 Keywords Search

//AC自动机
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std ;

const int maxn = 5555555 ;
class AC_auto
{
private :
    int tot , fail[maxn] , val[maxn] , c[26][maxn] ;
    queue<int> Q ;
    int new_node ()
    {
        int i ;
        fail[tot] = val[tot] = 0 ;
        for ( i = 0 ; i < 26 ; i ++ ) c[i][tot] = 0 ;
        return tot ++ ;
    }
public :
    void init ()
    {
        tot = 0 ; new_node () ;
        while ( !Q.empty () ) Q.pop () ;
    }
    void insert ( char *s )
    {
        int now = 0 ;
        for ( ; *s ; s ++ )
        {
            int k = *s - 'a' ;
            if ( !c[k][now] ) c[k][now] = new_node () ;
            now = c[k][now] ;
        }
        val[now] ++ ;
    }
    void get_fail ()
    {
        int i , u = 0 , j , e ;
        for ( i = 0 ; i < 26 ; i ++ ) if ( c[i][u] ) Q.push ( c[i][u] ) ;
        while ( !Q.empty () )
        {
            u = Q.front () ;
            Q.pop () ;
            for ( i = 0 ; i < 26 ; i ++ )
            {
                if ( !c[i][u] )
                {
                    c[i][u] = c[i][fail[u]] ;
                    continue ;
                }
                e = c[i][u] ;
                j = fail[u] ;
                fail[e] = c[i][j] ;
                Q.push ( e ) ;
            }
        }
    }
    int work ( char *s )
    {
        int u = 0 , i , e , ret = 0 ;
        for ( ; *s ; s ++ )
        {
            int k = *s - 'a' ;
            u = c[k][u] ;
            e = u ;
            while ( e )
            {
                if ( val[e] )
                {
                    ret += val[e] ;
                    val[e] = 0 ;
                }
                e = fail[e] ;
            }
        }
        return ret ;
    }
} ac ;
char s[maxn] ;
int main ()
{
    int cas , n ;
    scanf ( "%d" , &cas ) ;
    while ( cas -- )
    {
        scanf ( "%d" , &n ) ;
        ac.init () ;
        while ( n -- )
        {
            scanf ( "%s" , s ) ;
            ac.insert ( s ) ;
        }
        ac.get_fail () ;
        scanf ( "%s" , s ) ;
        printf ( "%d\n" , ac.work ( s ) ) ;
    }
}

再来个java版的ac自动机模板

import java.io.*;
import java.util.*;
import java.math.*;

class Que {
	int[] q = new int[1111111];
	int tail, star;

	void init() {
		star = 1;
		tail = 0;
	}

	void push(int v) {
		q[++tail] = v;
	}

	void pop() {
		star++;
	}

	int front() {
		return q[star];
	}

	int empty() {
		if (star > tail)
			return 1;
		else
			return 0;
	}
}



class AC_auto {
	int tot;
	int[][] c = new int[26][255555];
	int[] fail = new int[255555];
	int[] id = new int[255555];
	Que Q = new Que();

	int new_node() {
		int i;
		for (i = 0; i < 26; i++)
			c[i][tot] = 0;
		fail[tot] = id[tot] = 0;
		return tot++;
	}

	void init() {
		tot = 0;
		Q.init();
		new_node();
	}

	char[] s1 = new char[111111];

	void insert(String s) {
		s1 = s.toCharArray();
		int now = 0;
		int l = s1.length, i;
		for (i = 0; i < l; i++) {
			int k = s1[i] - 'a';
			if (c[k][now] == 0)
				c[k][now] = new_node();
			now = c[k][now];
		}
		id[now]++;
	}

	void get_fail() {
		int u = 0, e, i;
		for (i = 0; i < 26; i++)
			if (c[i][u] != 0)
				Q.push(c[i][u]);
		while (Q.empty() == 0) {
			u = Q.front();
			Q.pop();
			for (i = 0; i < 26; i++) {
				if (c[i][u] != 0) {
					e = c[i][u];
					fail[e] = c[i][fail[u]];
					Q.push(e);
				} else
					c[i][u] = c[i][fail[u]];
			}
		}
	}

	int work(String s) {
		s1 = s.toCharArray();
		int l = s1.length;
		int i, u = 0, j, sum = 0;
		;
		for (i = 0; i < l; i++) {
			int k = s1[i] - 'a';
			u = c[k][u];
			j = u;
			while (j != 0) {
				if (id[j] != 0) {
					sum += id[j];
					id[j] = 0;
				}
				j = fail[j];
			}
		}
		return sum;
	}

}

public class Main {

	static InputStream inputstream = System.in;
    static PrintStream outputstream = System.out;
    static InputReader in = new InputReader(inputstream);
    static PrintWriter out = new PrintWriter(outputstream);
    
	public static void main(String args[]) throws Exception {

 		 Main task = new Main();
		 task.main();
		 out.close () ;
	}

	String s;
	static AC_auto ac = new AC_auto();

	void main() throws Exception {
		int cas, n;
		cas = in.nextInt();
		for (; cas > 0; cas--) {
			ac.init();
			n = in.nextInt();
			for (; n > 0; n--) {
				s = in.next();
				ac.insert(s);
			}
			ac.get_fail();
			s = in.next();
			out.println(ac.work(s));
		}
	}
}

class InputReader {
	BufferedReader reader;
	StringTokenizer tokenizer;

	InputReader(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}

	String next() {
		if (!hasNext())
			throw new RuntimeException();
		return tokenizer.nextToken();
	}

	boolean hasNext() {
		while (tokenizer == null || !tokenizer.hasMoreTokens())
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (Exception e) {
				return false;
			}
		return true;
	}

	long nextLong() {
		return Long.parseLong(next());
	}

	int nextInt() {
		return Integer.parseInt(next());
	}
}


你可能感兴趣的:(AC自动机)