【hdu2222】【poj2945】AC自动机入门题

HDU2222 传送门

题目分析

裸题:注意构建自动机用的是模式串,思想和kmp很类似。

code:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int N = 1e4 + 5, M = 55, L = 1e6 + 5;

int T, n, tot, vst[N * M], vt;
char t[M], s[L];

struct node{
    int trans[30], fail;
    bool end;
    inline void clear(){
        fail = 0;
        memset(trans, 0, sizeof trans);
        end = false;
    }
}trie[N * M];

inline void insert(){
    int pos = 1, len = strlen(t + 1);
    for(int i = 1; i <= len; i++){
        if(!trie[pos].trans[t[i] - 'a' + 1])
            trie[trie[pos].trans[t[i] - 'a' + 1] = ++tot].clear();
        pos = trie[pos].trans[t[i] - 'a' + 1];
    }
    trie[pos].cnt++;
}

inline void buildFail(){
    static int qn, que[N * M];
    que[qn = 1] = 1;
    for(int ql = 1; ql <= qn; ql++){
        int u = que[ql];
        for(int i = 1; i <= 26; i++){
            int v = trie[u].fail;
            while(!trie[v].trans[i]) v = trie[v].fail;
            v = trie[v].trans[i];
            int w = trie[u].trans[i];
            if(w) trie[w].fail = v, que[++qn] = w;
            else trie[u].trans[i] = v;
        }
    }
}

int main(){
    scanf("%d", &T);
    for(int i = 1; i <= 26; i++) trie[0].trans[i] = 1;
    while(T--){
        ++vt;
        trie[tot = 1].clear();
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            scanf("%s", t + 1);
            insert();
        }
        buildFail();
        scanf("%s", s + 1);
        int len = strlen(s + 1), tmp, now = 1, ans = 0;
        for(int i = 1; i <= len; i++){
            now = trie[now].trans[s[i] - 'a' + 1];
            tmp = now;
            while(tmp && vst[tmp] != vt){
                vst[tmp] = vt;
                ans += trie[tmp].cnt;
                tmp = trie[tmp].fail;
            }
        }
        printf("%d
", ans);
    }
}

POJ2945

传送门

题目分析

还是裸题,在字符串结束的地方打上标记

code

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int N = 2e4 + 5, M = 25;
int n, m, ans[N];
struct node{
	node* trans[5];
	int cnt;
}trie[N * M], *tail = trie, *root;
char s[M];

inline node* newNode(){
	node *x = tail++;
	memset(x->trans, 0, sizeof x->trans);
	x->cnt = 0;
	return x;
}

inline int getVal(char t){
	switch(t){
		case 'A': return 1;
		case 'C': return 2;
		case 'G': return 3;
		case 'T': return 4;
	}
}

inline void insert(){
	node *pos = root;
	for(int i = 1; i <= m; i++){
		int v = getVal(s[i]);
		if(pos->trans[v] == NULL)
			pos->trans[v] = newNode();
		pos = pos->trans[v];
	}
	ans[pos->cnt]--;
	ans[++pos->cnt]++;
}

int main(){
	while(scanf("%d%d", &n, &m), n + m){
		memset(ans, 0, sizeof ans);
		tail = trie;
		root = newNode();
		for(int i = 1; i <= n; i++){
			scanf("%s", s + 1);
			insert();
		}
		for(int i = 1; i <= n; i++) printf("%d
", ans[i]);
	}
}
原文地址:https://www.cnblogs.com/CzYoL/p/7449822.html