zoukankan      html  css  js  c++  java
  • 白兔的字符串(字符串hash+模拟map)

    链接:https://ac.nowcoder.com/acm/problem/15253

    题目描述

    白兔有一个字符串T。白云有若干个字符串S1,S2..Sn

    白兔想知道,对于白云的每一个字符串,它有多少个子串是和T循环同构的。

    提示:对于一个字符串a,每次把a的第一个字符移动到最后一个,如果操作若干次后能够得到字符串b,则a和b循环同构。

    所有字符都是小写英文字母

    输入描述:

    第一行一个字符串T(|T|<=10^6)第二行一个正整数n (n<=1000)接下来n行为S1~Sn (|S1|+|S2|+…+|Sn|<=10^7),max(|S1|,|S2|,|S3|,|S4|,..|Sn|)<=10^6

    具体思路:

    首先把字符串T放大一倍,这样就能找到所有的T的长度为len的情况了。然后hash一遍,标记一下。

    然后对于输入的T个字符串,处理他的每个长度为len的子串,看是否被标记过。

    (map会超时,可以模拟map)

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define ll long long
     4 # define ull unsigned long long
     5 const int mod = 1e9+7;
     6 const int maxn = 1e6+100;
     7 const ull base = 131;
     8 const int mod_map = 14937;
     9 char str1[maxn],str2[maxn];
    10 ull ind[maxn],hash1[maxn],hash2[maxn];
    11 void init1()
    12 {
    13     ind[0]=1ll;
    14     for(int i=1; i<maxn; i++)
    15     {
    16         ind[i]=ind[i-1]*base;
    17     }
    18 }
    19 struct node
    20 {
    21     ull to;
    22     int nex;
    23 } edge[maxn];
    24 int  head[maxn],cnt;
    25 void addedge(ull x)// 类似于一个映射
    26 {
    27     int pos=x%mod_map;
    28     edge[cnt].to=x;
    29     edge[cnt].nex=head[pos];
    30     head[pos]=cnt++;
    31 }
    32 int Find(ull x)
    33 {
    34     int pos=x%mod_map;
    35     for(int i=head[pos]; i!=-1; i=edge[i].nex)
    36     {
    37         if(edge[i].to==x)
    38             return 1;
    39     }
    40     return 0;
    41 }
    42 ull get_sub1(int l,int r)
    43 {
    44     return hash1[r]-hash1[l-1]*ind[r-l+1];
    45 }
    46 ull get_sub2(int l,int r)
    47 {
    48     return hash2[r]-hash2[l-1]*ind[r-l+1];
    49 }
    50 void init2()
    51 {
    52     int len=strlen(str1+1);
    53     hash1[0]=0;
    54     for(int i=len+1; i<=len+len; i++)
    55     {
    56         str1[i]=str1[i-len];
    57     }
    58     for(int i=1; i<=len+len; i++)
    59     {
    60         hash1[i]=hash1[i-1]*base+(ull)(str1[i]);
    61         if(i>=len)
    62         {
    63             ull tmp=get_sub1(i-len+1,i);
    64             addedge(tmp);
    65         }
    66     }
    67 }
    68 int main()
    69 {
    70     memset(head,-1,sizeof(head));
    71     init1();
    72     scanf("%s",str1+1);
    73     int len1=strlen(str1+1);
    74     init2();
    75     int T;
    76     scanf("%d",&T);
    77     while(T--)
    78     {
    79         int ans=0;
    80         scanf("%s",str2+1);
    81         int  len2=strlen(str2+1);
    82         for(int i=1; i<=len2; i++)
    83         {
    84             hash2[i]=hash2[i-1]*base+(ull)(str2[i]);
    85             if(i>=len1)
    86                 if(Find(get_sub2(i-len1+1,i)))
    87                     ans++;
    88         }
    89         printf("%d
    ",ans);
    90     }
    91     return 0;
    92 }
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define ll long long
     4 # define ull unsigned long long
     5 //# define ull (unsigned long long)
     6 const int maxn = 2e6+100;
     7 const int mod_map = 14937;
     8 const ull base = 131;
     9 ull ind[maxn];
    10 ull hash1[maxn],hash2[maxn];
    11 char str[maxn];
    12 vector<ull>Edge[maxn];
    13 void add(ull t)
    14 {
    15     ull tmp=t%mod_map;
    16     Edge[tmp].push_back(t);
    17 }
    18 ull getsub1(int l,int r)
    19 {
    20 return hash1[r]-hash1[l-1]*ind[r-l+1];
    21 }
    22 ull getsub2(int l,int r)
    23 {
    24 return hash2[r]-hash2[l-1]*ind[r-l+1];
    25 }
    26 bool Find(ull tmp)
    27 {
    28     ull pos=tmp%mod_map;
    29     for(int i=Edge[pos].size()-1; i>=0; i--)
    30     {
    31         if(Edge[pos][i]==tmp)
    32             return true;
    33     }
    34     return false;
    35 }
    36 void init()
    37 {
    38     ind[0]=1ll;
    39     for(int i=1; i<maxn; i++)
    40     {
    41         ind[i]=ind[i-1]*base;
    42     }
    43     int len=strlen(str+1);
    44     for(int i=1+len; i<=len+len; i++)
    45     {
    46         str[i]=str[i-len];
    47     }
    48     for(int i=1; i<=len+len; i++)
    49     {
    50         hash1[i]=hash1[i-1]*base+(ull)(str[i]);
    51         if(i>=len)
    52         {
    53             add(getsub1(i-len+1,i));
    54         }
    55     }
    56 }
    57 int main()
    58 {
    59     scanf("%s",str+1);
    60     int tmp=strlen(str+1);
    61     init();
    62     int T;
    63     scanf("%d",&T);
    64     while(T--)
    65     {
    66         scanf("%s",str+1);
    67         int len=strlen(str+1);
    68         int ans=0;
    69         for(int i=1; i<=len; i++)
    70         {
    71             hash2[i]=hash2[i-1]*base+(ull)(str[i]);
    72             if(i>=tmp)
    73             {
    74                 if(Find(getsub2(i-tmp+1,i)))
    75                     ans++;
    76             }
    77         }
    78         printf("%d
    ",ans);
    79     }
    80     return 0;
    81 }
    vector版
  • 相关阅读:
    JAVA生成问答式验证码图片,支持加减算法
    kaptcha Java验证码
    字母数字、字母、汉字验证码 (java)
    java实现点击图片文字验证码
    java随机生成字符串(字符随机生成类 生成随机字符组合)
    分布式和集群的区别
    【nginx】配置Nginx实现负载均衡
    【Tomcat】一台电脑上运行多个tomcat
    【nginx+tomcat集群】Nginx1.12.2+Tomcat7集群+负载均衡+Session共享
    【nginx】nginx的安装及测试
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10878030.html
Copyright © 2011-2022 走看看