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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章