• 字符串hash


    Oulipo 

    Problem's Link

    ----------------------------------------------------------------------------

    Mean: 

    给你一个模式串P和一个母串S,让你统计P串在S串中出现的次数.

    analyse:

    一开始想到的就是使用KMP,就用KMP写了,93ms,挺快的.

    我又用AC自动机写了一遍,万万没想到竟然超时了.

    后来看别人有用字符串hash写的,于是又用字符串hash写了一遍,代码30+行,而且速度也挺快,173ms.

    字符串hash确实是一个好东西 在字符串hash中又学到了unsigned long long超范围后会自动对2^64取模,省去了手动取模.

    Time complexity: O(N+M)

     

    view code

     1.字符串hash代码

    #include<stdio.h>
    #include<string.h>
    #define ULL unsigned long long
    int 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 ",ans);
       }
       return 0;
    }

    2.KMP代码

    // 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 long
    using 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 ",KMP(s1,s2));
       }
       return 0;
    }

    3.AC自动机(TLE)

    /**
    * -----------------------------------------------------------------
    * Copyright (c) 2016 crazyacking.All rights reserved.
    * -----------------------------------------------------------------
    *       Author: crazyacking
    *       Date  : 2016-01-18-23.59
    */
    #include <queue>
    #include <cstdio>
    #include <set>
    #include <string>
    #include <stack>
    #include <cmath>
    #include <climits>
    #include <map>
    #include <cstdlib>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long(LL);
    typedef unsigned long long(ULL);
    const double eps(1e-8);

    const int N = 1001000;
    char str[N];
    struct node
    {
       node *next[30];
       node *fail;
       int count;
       node()
       {
           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)
    {
       node *p = root;
       int i = 0, index;
       while(str[i])
       {
           index = str[i] - 65;
           if(p->next[index] == NULL)
               p->next[index] = new node();
           p = p->next[index];
           i++;
       }
       p->count++;
    }
    void build_ac_automation(node *root)
    {
       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)
    {
       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);
           p = p->fail;
           p = p->next[index];
           if(p == NULL)
               p = root;
           node *temp = p;
           while(temp != root && temp->count != -1)
           {
               if(temp->count>0)
               {
                   cnt ++;
               }
               temp = temp->fail;
           }
           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 ",Query(root));
       }
       return 0;
    }

    --------------------------------------------------------- End.

    转载请注明:http://www.cnblogs.com/crazyacking/

  • 相关阅读:
    POJ1270 Following Orders[拓扑排序所有方案 Kahn]
    拓扑排序 POJ2367Genealogical tree[topo-sort]
    如何使用MySQL Workbench创建数据库存储过程
    sql server数据库中 smallint, int ,bigint ,tinyint的区别与长度
    now() 的用法
    存储过程制造数据
    JMeter—系统性能分析思路
    JMeter—监听器
    JMeter—断言
    Jmeter后置处理器之JSON Extractor
  • 原文地址:https://www.cnblogs.com/crazyacking/p/4005895.html
Copyright © 2020-2023  润新知