String hash-simple character matching --- poj 3461

Source: Internet
Author: User
Oulipo Problem's link: http://poj.org/problem? Id = 3461

 

Mean: 

We will give you a mode string P and a parent string s, so that you can count the number of occurrences of the P string in the S string.

Analyze:

The first thing I thought of was using KMP, which was written in KMP, 93 ms, which was fast. I wrote it again using an AC automatic machine (purely for entertainment). I never expected it to have timed out. Is it my wrong posture?

Later, let's look at other people's useful string hash writing. I heard that string hash is much more powerful than AC ry in some problems, so I wrote it again using string hash, which is really good, over 30 lines of code, and fast, 173 Ms. It is really a good thing to do with string hash. After hearing that string hash is proficient, there will be no other AC automatic machines or Suffix Arrays to solve many problems.

After the unsigned long is learned in the string hash, it will automatically modulo 2 ^ 64. The hash tool saves the manual modulo.

Time Complexity:O (N * m)

 

Source code:

 

String hash code:

#include<stdio.h>#include<string.h>#define ULL unsigned long longint seed=100;char s1[10005],s2[1000005];int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%s%s",s1,s2);        int len1=strlen(s1),len2=strlen(s2);        ULL a1=0,a2=0,l1=1;        for(int i=0;i<len1;++i)        {            a1=a1*seed+(s1[i]-‘A‘+1);            l1*=seed;        }        for(int i=0;i<len1;++i)        {            a2=a2*seed+(s2[i]-‘A‘+1);        }        int ans=0;        if(a1==a2) ans++;        for(int i=len1;i<len2;++i)        {            a2=a2*seed+(s2[i]-‘A‘+1)-l1*(s2[i-len1]-‘A‘+1);            if(a2==a1) ans++;        }        printf("%d\n",ans);    }    return 0;}

KMP code:

// Memory   Time// 1347K     0MS// by : Snarl_jsb// 2014-10-04-11.53#include<algorithm>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<vector>#include<queue>#include<stack>#include<map>#include<string>#include<climits>#include<cmath>#define N 1000010#define LL long longusing namespace std;char s1[10005],s2[1000005];vector<int> next;void GetNext(char s[]){    int len=strlen(s),k=0;    next.clear();    next.push_back(0);    for(int i=1;i<len;++i)    {        while(k!=0&&s[i]!=s[k])            k=next[k-1];        if(s[i]==s[k])            k++;        next.push_back(k);    }}int KMP(char s1[],char s2[]){    int l1=strlen(s1),l2=strlen(s2);    int k=0,ans=0;;    for(int i=0;i<l2;++i)    {        while(k!=0&&s2[i]!=s1[k])            k=next[k-1];        if(s2[i]==s1[k])            k++;        if(k==l1)        {            ans++;            k=next[k-1];        }    }    return ans;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%s%s",s1,s2);        int len1=strlen(s1),len2=strlen(s2);        GetNext(s1);        printf("%d\n",KMP(s1,s2));    }    return 0;}

AC automatic machine timeout code (Qaq ):

// Memory time // 1347 K 0 Ms //: snarl_jsb // 2014-09-30-11.01 # include <algorithm> # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # include <map> # include <string> # include <climits> # include <cmath> # define ll long longusing namespace STD; const int n = 1001000; char STR [N]; struct node {node * Next [30]; // each node corresponds to the pointer node * fail with 30 letters; // mismatched pointer int Count; // node () // constructor initialization {for (INT I = 0; I <30; I ++) next [I] = NULL; Count = 0; fail = NULL ;}} * Q [N]; node * root; int head, tail; void insert (char * Str) // insert a word. it is equivalent to building a trie tree {node * P = root; int I = 0, index; while (STR [I]) {Index = STR [I]-65; // convert it to a relative number to save if (p-> next [Index] = NULL) // The letter has not been inserted with p-> next [Index] = new node (); // apply for a node P = p-> next [Index] for the letter; // move it to the next I ++;} p-> count ++; // record the node's Total number of times of insertion of Words} void build_ac_automation (node * root) // BFS creates a fail pointer {root-> fail = NULL; Q [tail ++] = root; while (Head <tail) {node * temp = Q [head ++]; node * P = NULL; For (INT I = 0; I <30; I ++) {If (temp-> next [I]! = NULL) {If (temp = root) temp-> next [I]-> fail = root; else {P = temp-> fail; while (P! = NULL) {If (p-> next [I]! = NULL) {temp-> next [I]-> fail = p-> next [I]; break;} p = p-> fail ;} if (P = NULL) temp-> next [I]-> fail = root;} Q [tail ++] = temp-> next [I] ;}} int Total = 0; int query (node * root) // match + statistics {int I = 0, CNT = 0, index; node * P = root; int idx = 0; while (STR [I]) {Index = STR [I]-65; while (p-> next [Index] = NULL & P! = Root) // The prefix is the same, so no matter which pointer goes to the node where count is not 0, then the words represented by this node match successfully. P = p-> fail; // if the word is not matched, the p Pointer Points to P-> fail. (equivalent to the next array of KMP) P = p-> next [Index]; // because the current location is the parent node, so you need to move down a position if (P = NULL) P = root; // If the match fails, move to root and start matching node * temp = P again; // while (temp! = Root & temp-> count! =-1) // statistics -- if the match is successful, count> 1 indicates the number of words that the node represents; otherwise, the node does not have the word {If (temp-> count> 0) {CNT ++; // count the number of times the word appears} // temp-> COUNT =-1; // mark it as-1, indicating that the word has been added to CNT. You do not need to count temp => fail again next time; // determine the matching condition on the entire chain} I ++;} return CNT;} int main () {int t; CIN> T; while (t --) {head = tail = 0; root = new node (); scanf ("% s", STR); insert (STR); build_ac_automation (Root ); scanf ("% s", STR); // query (Root); printf ("% d \ n", query (Root);} return 0 ;}

  

String hash-simple character matching --- poj 3461

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.