AC Automaton reinforced version UVA 1449-dominating Patterns

Source: Internet
Author: User
Tags printf repetition strlen

AC Automata Initial action A common example is to give n words, and then give an article containing M characters, so you can find out how many words have appeared in the article.

Of course this is not the full effect of AC automata.

This article is an example, give a few words, query the text in the most occurrences of the word, if not unique, output in the order of input

AC automata is just learned, modify the fact that they do not have the ability to refer to other people's code, modify their own template

First look at the topic Http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=505&page=show_ problem&problem=4195

Look at my own AC template (pre-modified)

/*************************************************///ac Automaton by Pilgrim////maxlen mode string length//str mode string (to be matched)//keyword to be entered    Whether the word//cnt is the last node of the word, insert,//when the word insertion is complete, the last node of the Cnt=1//root's fail is NULL////Initialize//root=cur=trie;
Cur points to the end address of the storage cell//head = tail = 0;
ROOT->CLR (); Also, the/*************************************************/of the CLR () is needed to create the node when the insert is created #define MaxLen 1000010 #define

Maxtrie 500010 #define Wordlen Wuyi #define KIND-Char Str[maxlen],keyword[wordlen];
    struct node{Node *fail;   Node *next[kind];
    The/*next array is the child of the current node */int cnt;
        void CLR () {fail = NULL;
        CNT = 0;
    memset (next,0,sizeof (next) *kind);  }}trie[maxtrie],*q[maxtrie],*root,*cur; /* See the first comment */int head,tail;/* queue start and end initialization head = tail = 0*/void Insert (char s[])/* Insert Word to tries */{int Idx,i,n=strlen (s)
    ;
    Node *p=root;
        for (int i=0;i<n;i++) {idx = s[i]-' a '; if (p->next[idx]==null) {/*null is allocated space only to handle this situation: he her two words, the dictionary tree they are in the sameBranches, R and E cnt are all 1*/p->next[idx]=++cur;
        P-&GT;NEXT[IDX]-&GT;CLR ();
    } p=p->next[idx];   } p->cnt++;
                  /* Insert complete, here is p->cnt++ rather than p->cnt=1;

is to exclude this situation: her er these two words, if the p->cnt=1 will only be a word count, but also the problem is that the template string is keyword repetition of the time will be the problem * *}
    void Build_ac () {Node *p,*tmp;
    root->fail=null;////Q[tail++]=root;
        while (Head!=tail) {p=q[head++];
                for (int i=0;i<kind;i++) {if (P->next[i]) {q[tail++]=p->next[i];
                if (p = = root) {p->next[i]->fail = root;
                    } else {tmp=p->fail; while (Tmp!=null) {if (Tmp->next[i])/*tmp->next[i] p->next[i] I all tables +i ' A ' if tmp->next[i].
  =null, stating that there had been ' a ' +i*/{                          p->next[i]->fail=tmp->next[i];
                        Break
                    } tmp=tmp->fail;
                } if (tmp = = NULL) P->next[i]->fail = root;
    }}}}} int Query () {int Ans=0,n=strlen (str), IDX;
    Node *tmp,*p=root;
        for (int i=0;i<n;i++) {idx=str[i]-' a ';
        while (P->next[idx]==null && p!=root)//jump failed pointer, such as has reached the lowest level p=p->fail;
        p=p->next[idx];
        if (p==null)/* If the letter does not exist in trie, let the letter pointer point to root*/p=root;	TMP = P;                               P does not move, TMP computes suffix string while (tmp!=root && tmp->cnt!=-1)//simulation can be known, tmp->cnt!=-1 {              is to prevent repeated counts on the same string ans+=tmp->cnt;
            For example the word is her str is herher at this time the answer is only 1 tmp->cnt=-1; tmp=tmp->fail;//The pointer moves the next character to continue the match}} return ans;
    } void Init_ac () {cur = root = Trie;
    ROOT-&GT;CLR ();
Head = tail = 0;
 }

First, we analyze several problems that need to be dealt with:

1, Count.

AC automata in order not to repeat the count, there is such a sentence tmp->cnt=-1;

This sentence must be rid of

Also, note that even if it is not the end of the word, you can enter this loop, and each time you enter this loop, if/* (2)//is not handled properly, it will count more.

    while (Tmp!=root && tmp->cnt!=-1)/* (1) */
        {                               
            ans+=tmp->cnt;              
            tmp->cnt=-1;/* (2) */
            tmp=tmp->fail;//pointer moves down character to continue matching
        }
Need to make two changes,/* (1) */place, tmp->cnt>=1 only into the loop;/* (2) */place, array record occurrences


2, when some word appears the same number of times, how to output all.

The answer is to record the maximum number of occurrences Mmax, and then sweep the array of all occurrences of the word, as long as the Mmax is the same as the output.


The last Code

#include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include <map

> Using namespace std; #define MaxLen 1000010 #define Maxtrie 500010 #define Wordlen #define KIND #define N 201 Char Str[maxlen],keyword[w
Ordlen];
Char All[n][wordlen];
    int num[n];/* stores the number of strings */struct node{Node *fail;   Node *next[kind];
    The/*next array is the child of the current node */int cnt,id;
        void CLR () {fail = NULL;
        CNT = 0;
        Id=-1;
    memset (next,0,sizeof (next) *kind);  }}trie[maxtrie],*q[maxtrie],*root,*cur; /* See the first comment */int head,tail;/* queue start and end initialize head = tail = 0*/void Insert (char s[],int ID)/* insert Word to tries */{int idx,i,n=st
    Rlen (s);
    Node *p=root;
        for (int i=0;i<n;i++) {idx = s[i]-' a '; if (p->next[idx]==null) {/*null is allocated space only to deal with this situation: he her two words, the dictionary tree they are in the same branch, R and E of CNT are 1*/P-&GT;NEXT[IDX]=++CU
            R
        P-&GT;NEXT[IDX]-&GT;CLR ();
    } p=p->next[idx];
    }p->cnt++;
                  /* Insert complete, here is p->cnt++ rather than p->cnt=1;
    is to exclude this situation: her er these two words, if the p->cnt=1 will only be counted as a word, but also the problem is that the template string is keyword repeated when the problem will occur */
p->id=id;
    } void Build_ac () {Node *p,*tmp;
    root->fail=null;////Q[tail++]=root;
        while (Head!=tail) {p=q[head++];
                for (int i=0;i<kind;i++) {if (P->next[i]) {q[tail++]=p->next[i];
                if (p = = root) {p->next[i]->fail = root;
                    } else {tmp=p->fail; while (Tmp!=null) {if (Tmp->next[i])/*tmp->next[i] p->next[i] I all tables +i ' A ' if tmp->next[i].
                            =null, stating that previous ' a ' +i*/{p->next[i]->fail=tmp->next[i];
                   Break     } tmp=tmp->fail;
                } if (tmp = = NULL) P->next[i]->fail = root;
    }}}}} int Query () {int Ans=0,n=strlen (str), IDX;
    Node *tmp,*p=root;
        for (int i=0;i<n;i++) {idx=str[i]-' a ';
        while (P->next[idx]==null && p!=root)//jump failed pointer, such as has reached the lowest level p=p->fail;
        p=p->next[idx];
        if (p==null)/* If the letter does not exist in trie, let the letter pointer point to root*/p=root;	TMP = P;                               P does not move, TMP computes suffix string while (tmp!=root && tmp->cnt>=1)//simulation can be known, tmp->cnt!=-1 {
            is to prevent repeated counts on the same string ans+=tmp->cnt;
            if (tmp->id!=-1)//For example the word is her str is herher at this time the answer is only 1 num[tmp->id]++;
            tmp->cnt=-1;
tmp=tmp->fail;//The pointer moves the next character to continue the match}} return ans;
 } void Init_ac () {cur = root = Trie;   ROOT-&GT;CLR ();
    Head = tail = 0;
memset (num,0,sizeof (num));

    } int main () {int n;
        while (scanf ("%d", &n)!=eof && N) {init_ac ();
            for (int i=0;i<n;i++) {scanf ("%s", keyword);
            strcpy (All[i],keyword);
        Insert (Keyword,i);
        } scanf ("%s", str);
        Build_ac ();
        int Mmax =-1;
        Query ();
        for (int i=0;i<n;i++) Mmax = max (Mmax,num[i]);
        printf ("%d\n", Mmax);
    for (int i=0;i<n;i++) if (Num[i]==mmax) puts (all[i]);
} return 0;
 }

Slightly slower on the top, a little faster, a little change in the query loop

#include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include <map

> Using namespace std; #define MaxLen 1000010 #define Maxtrie 500010 #define Wordlen #define KIND #define N 201 Char Str[maxlen],keyword[w
Ordlen];
Char All[n][wordlen];
    int num[n];/* stores the number of strings */struct node{Node *fail;   Node *next[kind];
    The/*next array is the child of the current node */int cnt,id;
        void CLR () {fail = NULL;
        CNT = 0;
        Id=-1;
    memset (next,0,sizeof (next) *kind);  }}trie[maxtrie],*q[maxtrie],*root,*cur; /* See the first comment */int head,tail;/* queue start and end initialize head = tail = 0*/void Insert (char s[],int ID)/* insert Word to tries */{int idx,i,n=st
    Rlen (s);
    Node *p=root;
        for (int i=0;i<n;i++) {idx = s[i]-' a '; if (p->next[idx]==null) {/*null is allocated space only to deal with this situation: he her two words, the dictionary tree they are in the same branch, R and E of CNT are 1*/P-&GT;NEXT[IDX]=++CU
            R
        P-&GT;NEXT[IDX]-&GT;CLR ();
    } p=p->next[idx];
    }p->cnt++;
                  /* Insert complete, here is p->cnt++ rather than p->cnt=1;
    is to exclude this situation: her er these two words, if the p->cnt=1 will only be counted as a word, but also the problem is that the template string is keyword repeated when the problem will occur */
p->id=id;
    } void Build_ac () {Node *p,*tmp;
    root->fail=null;////Q[tail++]=root;
        while (Head!=tail) {p=q[head++];
                for (int i=0;i<kind;i++) {if (P->next[i]) {q[tail++]=p->next[i];
                if (p = = root) {p->next[i]->fail = root;
                    } else {tmp=p->fail; while (Tmp!=null) {if (Tmp->next[i])/*tmp->next[i] p->next[i] I all tables +i ' A ' if tmp->next[i].
                            =null, stating that previous ' a ' +i*/{p->next[i]->fail=tmp->next[i];
                   Break     } tmp=tmp->fail;
                } if (tmp = = NULL) P->next[i]->fail = root;
    }}}}} int Query () {int Ans=0,n=strlen (str), IDX;
    Node *tmp,*p=root;
        for (int i=0;i<n;i++) {idx=str[i]-' a ';
        while (P->next[idx]==null && p!=root)//jump failed pointer, such as has reached the lowest level p=p->fail;
        p=p->next[idx];
        if (p==null)/* If the letter does not exist in trie, let the letter pointer point to root*/p=root;	TMP = P;                   P does not move, TMP computes suffix string while (tmp!=root)//simulation can be known, tmp->cnt!=-1 {if (tmp->cnt>=1) is to prevent repetition of the same string if (tmp->id!=-1)//such as the word is her str is herher at this time the answer is just 1 n
            um[tmp->id]++;
tmp=tmp->fail;//The pointer moves the next character to continue the match}} return ans;
    } void Init_ac () {cur = root = Trie;
    ROOT-&GT;CLR ();
    Head = tail = 0; memset (Num,0,siZeof (num));

    } int main () {int n;
        while (scanf ("%d", &n)!=eof && N) {init_ac ();
            for (int i=0;i<n;i++) {scanf ("%s", keyword);
            strcpy (All[i],keyword);
        Insert (Keyword,i);
        } scanf ("%s", str);
        Build_ac ();
        int Mmax =-1;
        Query ();
        for (int i=0;i<n;i++) Mmax = max (Mmax,num[i]);
        printf ("%d\n", Mmax);
    for (int i=0;i<n;i++) if (Num[i]==mmax) puts (all[i]);
} return 0;
 }


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.