zoukankan      html  css  js  c++  java
  • POJ2406Power StringsKMP循环节/哈希循环节

    Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).

    Input

    Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.

    Output

    For each s you should print the largest n such that s = a^n for some string a.

    Sample Input

    abcd aaaa ababab .

    Sample Output

    1 4 3

    Hint

    This problem has huge input, use scanf instead of cin to avoid time limit exceed.

     

    题意:

    求每个字符串最多是由多少个相同的子字符串重复连接而成的。

    如:ababab 则最多有3个 ab 连接而成。

     

    思路:两种方法求循环节的模板题。

     

    哈希:

     

     1 #include<stdio.h>
     2 #include<string.h>
     3 typedef unsigned long long ull;
     4 const int N=1e6+20;
     5 char a[N];
     6 ull p[N],sum[N],x=131;
     7 
     8 void init()
     9 {
    10     p[0]=1;
    11     for(int i=1; i<N; i++)
    12         p[i]=p[i-1]*x;
    13 }
    14 
    15 int main()
    16 {
    17     init();
    18     while(~scanf("%s",a+1))
    19     {
    20         if(a[1]=='.')
    21             break;
    22         int len=strlen(a+1);
    23         sum[0]=0;
    24         for(int i=1;i<=len;i++)//主串哈希值
    25             sum[i]=sum[i-1]*x+a[i];
    26         for(int i=1; i<=len; i++)
    27         {
    28             if(len%i!=0)
    29                 continue;//说明不存在该循环节
    30             int flag=0;
    31             for(int j=i; j<=len; j+=i)
    32             {   //ababab 
    33                 //i=2时 -> j=2、4、6
    34                 if((sum[j]-sum[j-i]*p[i])!=sum[i])
    35                 //(sum[2]-sum[2-2]*p[2])!=sum[2]
    36                 //(sum[4]-sum[4-2]*p[2])!=sum[2]
    37                 //(sum[6]-sum[6-2]*p[2])!=sum[2]
    38                 {
    39                     flag=1;
    40                     break;
    41                 }
    42             }
    43             if(flag==0)
    44             {
    45                 printf("%d\n",len/i);
    46                 break;
    47             }
    48         }
    49     }
    50     return 0;
    51 }

     

     

     

    KMP:

     思想:

    比如abcabcabcabc ,nextt[len]=9,len=12,所以len-next[len]=3肯定是len=12的因数,并且此时len-next[len]=3也肯定为最短循环节的长度,所以len/(len-next[len])=12/(12-9)=12/3=4,即循环节的个数,也就是出现过几次abc。

    如果不能整除说明不存在循环节,直接输出1即可。

    int w=len-nextt[len];
    if(len%w==0)
        printf("%d\n",len/w);
    else
        printf("1\n");

    详细代码如下:

     1 #include<stdio.h>
     2 #include<string.h>
     3 const int N=1e6+20;
     4 
     5 int nextt[N],len;
     6 char a[N];
     7 
     8 void getnext()
     9 {
    10     int i=0,j=-1;
    11     nextt[0]=-1;
    12     while(i<len)
    13     {
    14         if(j==-1||a[i]==a[j])
    15         {
    16             nextt[++i]=++j;
    17         }
    18         else
    19             j=nextt[j];
    20     }
    21 }
    22 
    23 int main()
    24 {
    25     while(~scanf("%s",a))
    26     {
    27         if(a[0]=='.')
    28             break;
    29         len=strlen(a);
    30         getnext();
    31         len=strlen(a);
    32         int w=len-nextt[len];
    33         if(len%w==0)
    34             printf("%d\n",len/w);
    35         else
    36             printf("1\n");
    37     }
    38     return 0;
    39 }
    View Code

     

  • 相关阅读:
    【arm】using as: GNU assember学习笔记
    【linux】gcc编译选项:-fomit-frame-pointer,-fno-tree-vectorize,-fno-strict-aliasing以及ARM相关选项
    【arm】armv8中通用寄存器的饱和指令实现(对标arm32:ssat,usat,qadd,qsub)
    【shell】常用的几种shell解释器:sh,bash,zsh,ash,csh
    【linux/Tools】Performance Profile Tools——perf and gprof
    【android】如何查看Android设备的CPU架构信息
    【arm】big-LITTLE architecture and How to check core, frequency, features of CPU and memory infos
    【python】创建excel文档.csv
    【mpeg4】MPEG-4 B帧帧间预测模式
    【linux】关于find命令查找的排序规则探索以及排序方法
  • 原文地址:https://www.cnblogs.com/OFSHK/p/11749335.html
Copyright © 2011-2022 走看看