java ac自动机_AC自动机模板(c++版和java版) | 学步园

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

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

的博客。

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

//AC自动机

#include

#include

#include

#include

using namespace std ;

const int maxn = 5555555 ;

class AC_auto

{

private :

int tot , fail[maxn] , val[maxn] , c[26][maxn] ;

queue 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());

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值