HDU2222
求匹配串中模式串出现的个数(不重复)
#include<cstdio>
#include<algorithm>
#include <iostream>
#include <string.h>
#include <vector>
#include <queue>
#include <math.h>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
const int maxn = 1e7;
int cnt;
struct node {
node *next[26];
node *fail;
int sum;
};
node *root;
char key[70];
node *q[maxn]; //模拟队列
int head, tail; //队列头尾
node *newnode;
char pattern[maxn];
int N;
void Insert(char *s)
{
node *p = root;
for(int i = 0; s[i]; i++)
{
int x = s[i] - 'a';
if(p->next[x] == NULL) {
newnode = (struct node *)malloc(sizeof(struct node));
for(int j = 0; j < 26; j++) newnode->next[j] = 0;
newnode->sum = 0;
newnode->fail = 0;
p->next[x] = newnode;
}
p = p->next[x];
}
p->sum++;
}
void build_fail_pointer()
{
head = 0;
tail = 1;
q[head] = root;
node *p;
node *temp;
while(head < tail)
{
temp = q[head++];
for(int i = 0; i < 26; i++)
{
if(temp->next[i]) {
if(temp == root) {
temp->next[i]->fail = root;
}
else {
p = temp->fail;
while(p)
{
if(p->next[i]) {
temp->next[i]->fail = p->next[i];
break;
}
p = p->fail;
}
if(p == NULL) temp->next[i]->fail = root;
}
q[tail++] = temp->next[i];
}
}
}
}
void ac_automation(char *ch)
{
node *p = root;
int len = strlen(ch);
for(int i = 0; i < len; i++)
{
int x = ch[i] - 'a';
while(!p->next[x] && p != root) p = p->fail;
p = p->next[x];
if(!p) p = root;
node *temp = p;
while(temp != root)
{
if(temp->sum >= 0) {
cnt += temp->sum;
temp->sum = -1;
}
else break;
temp = temp->fail;
}
}
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
root = (struct node *)malloc(sizeof(struct node));
for(int j = 0; j < 26; j++) root->next[j] = 0;
root->fail = 0;
root->sum = 0;
scanf("%d", &N);
for(int i = 1; i <= N; i++)
{
scanf("%s",key);
Insert(key);
}
scanf("%s", pattern);
cnt = 0;
build_fail_pointer();
ac_automation(pattern);
printf("%d\n",cnt);
}
return 0;
}
HiHo1036 确认匹配串中是否出现了模式串
#include<cstdio>
#include<algorithm>
#include <iostream>
#include <string.h>
#include <vector>
#include <queue>
#include <math.h>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
const int maxn = 1e6+5;
int cnt;
struct node {
node *next[26];
node *fail;
int sum;
};
node *root;
char key[maxn];
node *q[maxn]; //模拟队列
int head, tail; //队列头尾
node *newnode;
char pattern[maxn];
int N;
void Insert(char *s)
{
node *p = root;
for(int i = 0; s[i]; i++)
{
int x = s[i] - 'a';
if(p->next[x] == NULL) {
newnode = (struct node *)malloc(sizeof(struct node));
for(int j = 0; j < 26; j++) newnode->next[j] = 0;
newnode->sum = 0;
newnode->fail = 0;
p->next[x] = newnode;
}
p = p->next[x];
}
p->sum++;
}
void build_fail_pointer()
{
head = 0;
tail = 1;
q[head] = root;
node *p;
node *temp;
while(head < tail)
{
temp = q[head++];
for(int i = 0; i < 26; i++)
{
if(temp->next[i]) {
if(temp == root) {
temp->next[i]->fail = root;
}
else {
p = temp->fail;
while(p)
{
if(p->next[i]) {
temp->next[i]->fail = p->next[i];
break;
}
p = p->fail;
}
if(p == NULL) temp->next[i]->fail = root;
}
q[tail++] = temp->next[i];
}
}
}
}
void ac_automation(char *ch)
{
node *p = root;
int len = strlen(ch);
for(int i = 0; i < len; i++)
{
int x = ch[i] - 'a';
while(!p->next[x] && p != root) p = p->fail;
p = p->next[x];
if(!p) {
p = root;
}
node *temp = p;
while(temp != root)
{
if(temp->sum >= 0) {
cnt += temp->sum;
temp->sum = -1;
}
else break;
temp = temp->fail;
}
}
}
int main()
{
while(scanf("%d", &N) != EOF)
{
root = (struct node *)malloc(sizeof(struct node));
for(int j = 0; j < 26; j++) root->next[j] = 0;
root->fail = 0;
root->sum = 0;
scanf("%d", &N);
for(int i = 1; i <= N; i++)
{
scanf("%s", key);
Insert(key);
}
scanf("%s", pattern);
gets(pattern);
cnt = 0;
build_fail_pointer();
ac_automation(pattern);
printf(cnt ? "YES\n" : "NO\n");
}
return 0;
}