病毒侵袭持续中

分析:依然是一个模板题,不过在写建立失败指针的地方竟然写错了三次....看来现在状态不太好。
 
代码如下:
=========================================================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;

const int MAXN = 2e6+7;
const int MAXM = 26;
const int oo = 1e9+37;

char virus[1007][107], MumStr[MAXN];
int times[1007];

struct node
{
    node *Fail, *next[MAXM];
    int leaf;
};

void Insert(node *root, char s[], int num)
{
    node *p = root;

    for(int i=0; s[i]; i++)
    {
        int k = s[i] - 'A';

        if(p->next[k] == NULL)
            p->next[k] = new node();
        p = p->next[k];
    }

    p->leaf = num;
}
void GetFail(node *root)
{
    node *p = root, *temp;
    queue<node *> Q;

    for(int i=0; i<MAXM; i++)if(p->next[i])
    {///竟然头晕的把这个地方写错了三次....
        p->next[i]->Fail = root;
        Q.push(p->next[i]);
    }

    while(Q.size())
    {
        p = Q.front();
        Q.pop();

        for(int i=0; i<MAXM; i++)if(p->next[i])
        {
            temp = p->Fail;

            while(temp != NULL)
            {
                if(temp->next[i] != NULL)
                {
                    p->next[i]->Fail = temp->next[i];
                    break;
                }

                temp = temp->Fail;
            }

            if(temp == NULL)
                p->next[i]->Fail = root;

            Q.push(p->next[i]);
        }
    }
}
void FreeTrie(node *root)
{
    for(int i=0; i<MAXM; i++)
    {
        if(root->next[i])
            FreeTrie(root->next[i]);
    }

    free(root);
}
void Query(node *root)
{
    node *p = root, *temp;

    for(int i=0; MumStr[i]; i++)
    {
        if(MumStr[i] < 'A' || MumStr[i] > 'Z')
        {///排除不为大写英文的字符
            p = root;
            continue;
        }

        int k = MumStr[i] - 'A';

        while(!p->next[k] && p != root)
            p = p->Fail;

        if(!p->next[k])continue;

        temp = p = p->next[k];

        while(temp != root)
        {
            if(temp->leaf)
                times[temp->leaf] += 1;
            temp = temp->Fail;
        }
    }
}

int main()
{
    int N;

    while(scanf("%d", &N) != EOF)
    {
        node *root = new node();
        memset(times, 0, sizeof(times));

        for(int i=1; i<=N; i++)
        {
            scanf("%s", virus[i]);
            Insert(root, virus[i], i);
        }

        GetFail(root);

        scanf("%s", MumStr);
        Query(root);

        for(int i=1; i<=N; i++)
        {
            if(times[i])
                printf("%s: %d
", virus[i], times[i]);
        }

        FreeTrie(root);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/liuxin13/p/4750880.html