AC自动机应用(2)LA 4670出现次数最多的子串

分析:与我上一个博客几乎是一个题,只是由输出是否存在河蟹词语到输出重复次数最多的子串,并打印出来次数最多的子串

区别:加一个标签


#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>

using namespace std;

struct TrieNode
{
    int id;//标签
    struct TrieNode *next[26];
    struct TrieNode *behind;
};

typedef TrieNode Trie;

Trie *root;

Trie * CreateNode()//建立树的节点
{
    Trie *p=(Trie*)malloc(sizeof(Trie));
    p->id=0;
    for (int i=0;i<26;i++)
        p->next[i]=NULL;
    p->behind=NULL;
    return p;
}

void Insert(string s,int id)//建立字典树
{
    Trie *p=root;
    int len=s.size();
    for (int i=0;i<len;i++)
    {
        int id=s[i]-'a';
        if (p->next[id] == NULL)
        {
            p->next[id]=CreateNode();
            p=p->next[id];
        }
        else p=p->next[id];
    }
    p->id=id;
}

void AC()//生成Trie图 
{
    queue<Trie*> Q;
    for (int i=0;i<26;i++)
        if (!root->next[i])
        {
            root->next[i]=root;
        }
        else
        {
            root->next[i]->behind=root;
            Q.push(root->next[i]);
        }
    while (Q.size())
    {
        Trie *p=Q.front();
        Trie *q=p->behind;
        Q.pop();
        for (int i=0;i<26;i++)
        {
            if (!p->next[i])
            {
                p->next[i]=q->next[i];
            }
            else
            {
                p->next[i]->behind=q->next[i];
                Q.push(p->next[i]);
            }
        }
    }
}

void deal(Trie* T)//删除树
{
    if(T==NULL)
        return;
    for(int i=0;i<26;i++)
    {
        if(T->next[i]!=NULL)
            deal(T->next[i]);
    }
    free(T);
}

int main()
{
    map<string,int> P;
    string str[160];
    string s;
    int n;
    int maxn[151];
    while (scanf("%d",&n) && n)
    {
        root=CreateNode();
        getchar();
        for (int i=1;i<=n;i++)
        {
            cin>>str[i];
            Insert(str[i],i);
        }
        AC();
        cin>>s;
        memset(maxn,0,sizeof(maxn));
        Trie *p=root;
        int len=s.size();
        for (int i=0;i<len;i++)//Seach
        {
            int id=s[i]-'a';
            p=p->next[id];
            if (p->id > 0) maxn[p->id]++;
        }
        int ans=0;
        for (int i=1;i<=n;i++)
        {
            ans=max(ans,maxn[i]);
        }
        printf("%d\n",ans);
        for (int i=1;i<=n;i++)
            if (maxn[i] == ans)
                cout<<str[i]<<endl;
    }
    return 0;
}

你可能感兴趣的:(la,4670出现次数最多的子串AC)