UVA 1449 - Dominating Patterns(AC自动机)

uva 1449 - Dominating Patterns

题目链接

题意:给定一些模式串,再给一个文本,求这些模式串在文本中出现次数最多的串

思路:AC自动机的模板题目,注意字符串重复的处理

代码:

#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;

const int MAXNODE = 11000;
const int SIGMA_SIZE = 26;

struct AutoMac {

    int ch[MAXNODE][SIGMA_SIZE];
    int val[MAXNODE];
    int next[MAXNODE];
    int last[MAXNODE];
    int sz;
    
    int cnt[155];
    map<string, int> ms;

    void init() {
	sz = 1; 
	memset(ch[0], 0, sizeof(ch[0]));
	memset(cnt, 0, sizeof(cnt));
	ms.clear();
    }
    
    int idx(char c) {
	return c - 'a';
    }
    
    void insert(char *str, int v) {
	int n = strlen(str);
	int u = 0;
	for (int i = 0; i < n; i++) {
	    int c = idx(str[i]);
	    if (!ch[u][c]) {
		memset(ch[sz], 0, sizeof(ch[sz]));
		val[sz] = 0;
		ch[u][c] = sz++;
	    }
	    u = ch[u][c];
	}
	val[u] = v;
	ms[str] = v;
    }

    void getnext() {
	queue<int> Q;
	next[0] = 0;	
	for (int c = 0; c < SIGMA_SIZE; c++) {
	    int u = ch[0][c];
	    if (u) {next[u] = 0; Q.push(u); last[u] = 0;}
	}
	while (!Q.empty()) {
	    int r = Q.front(); Q.pop();
	    for (int c = 0; c < SIGMA_SIZE; c++) {
		int u = ch[r][c];
		if (!u) {
		    ch[r][c] = ch[next[r]][c];
		    continue;
		}
		Q.push(u);
		int v = next[r];
		while (v && !ch[v][c]) v = next[v];
		next[u] = ch[v][c];
		last[u] = val[next[u]] ? next[u] : last[next[u]];
	    }
	}
    }

    void print(int i, int j) {
	if (j) {
	    cnt[val[j]]++;
	    print(i, last[j]);
	}
    }

    void find(char *T) {
	int n = strlen(T);
	int j = 0;
	for (int i = 0; i < n; i++) {
	    int c = idx(T[i]);
	    j = ch[j][c];
	    if (val[j]) print(i, j);
	    else if (last[j]) print(i, last[j]);
	}
    }
};

const int N = 1000005;

AutoMac gao;

int n;
char s[155][75];    
char T[N];

int main() {
    int cas = 0;
    while (~scanf("%d", &n) && n) {
	gao.init();
	for (int i = 1; i <= n; i++) {
	    scanf("%s", s[i]);
	    gao.insert(s[i], i);
	}
	gao.getnext();
	scanf("%s", T);
	gao.find(T);
	int best = -1;
	for (int i = 1; i <= n; i++)
	    best = max(best, gao.cnt[i]);
	printf("%d\n", best);
	for (int i = 1; i <= n; i++)
	    if (best == gao.cnt[gao.ms[s[i]]])
		printf("%s\n", s[i]);
    }
    return 0;
}


你可能感兴趣的:(UVA 1449 - Dominating Patterns(AC自动机))