zoukankan      html  css  js  c++  java
  • poj2406(kmp算法)

    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.
    简单的kmp算法next数组的运用,此博客是为了我以后的学习引以为戒!!!

    大意:给出一个字符串 问它最多由多少相同的字串组成 (转载自https://www.cnblogs.com/zhanzhao/p/4761477.html)

    如  abababab由4个ab组成

    分析:

    kmp中的next数组求最小循环节的应用

    例如 

    ababab  next[6] = 4; 即

    ababab

       ababab

    1~4位  与2~6位是相同的

    那么前两位

    就等于3、4位

    3、4位就等于5、6位

    ……

    所以 如果 能整除  也就循环到最后了

    如果不能整除  

    就最后余下的几位不在循环内

    例如

    1212121

      1212121

    最后剩余1不能等于循环节

    难以置信我居然卡在这题三个小时,最后发现原因的我眼泪流下来,居然k的值设为-1就过了,一开始看到别人不同的代码还以为我算法思路错了,最终经过两个小时的研究(一次次模拟算法的运行QAQ)才发现算法思路一样,只是写法不同,只是我的代码在对于特殊数据时会卡死,顿时感觉要吐血,果然还是太菜了,打代码时不能分心,不能浮躁,不能一超时找不到问题就去百度,不能一看到别人代码不同就慌了神,怀疑自己对这个算法的学习产生了错误,果然还是要冷静啊,仔细看看自己的代码对于特殊数据是否会有bug,引以为戒引以为戒!

    #include<stdio.h>
    #include<string.h>
    char str[1000005];
    int next[1000005];
    int main ()
    {
      int i ,n;
      while(scanf("%s" ,str)!=EOF && str[0] != '.')
      {
        //printf("WWW ");
        n = strlen(str);
        int k = -1;
        next[0] = -1;
        for(i=1;i<n;i++)
        {
          //printf("%d %d ",i,k);
          while(k>-1&&str[k+1]!=str[i])
          {
            //printf("%d %c %c ",k,str[k],str[i]);
            k=next[k];
          }
          if(str[k+1]==str[i])
          k++;
          next[i]=k;      

        }
        int t=next[n-1]+1;
        if (n % (n-t)==0) printf("%d ", n / (n-t));
        else printf("%d ", 1);
      }
        return 0;
    }

    此代码核心的另一种写法(大同小异)

        int k = -1; 

        int j = 0;

        next[0] = -1; 
          while(j<n)
        {
          //printf("%d %d ",i,k);
          if(k==-1||s[j] == s[k])

          {

            next[++j]=++k;  

          }

          else

          k=next[k];   

        }

    我卡bug的代码

        n = strlen(str); //这代码咋一看没有错误,但是仔细观察后会发现当输入数据为aabbaa时这个代码会卡死,原因是当i=2时
        int k = 0; 
        next[0] = 0; 
        for(i=1;i<n;i++)
        {
          //printf("%d %d ",i,k);
          while(k>0&&str[k]!=str[i])//这个while语句会陷入死循环
          {
            //printf("%d %c %c ",k,str[k],str[i]);
            k=next[k];//k=next[k]=1,在这种情况下会一直执行这个while语句,睡完午觉后才突然发现。。。。,
          }
          if(str[k]==str[i])
          k++;
          next[i]=k;      

        }

    总之,以后打代码不能总是只考虑到一种可能出错的方式,要看看自己的代码是否会卡在某些特殊数据上,如果遇到错误千万不能心急,首先要冷静下来,仔细看看自己的代码可能出错的地方,可能会发生错误的地方和数据,只有这样才能高效的找出问题的所在!!!

  • 相关阅读:
    Day10
    Day9
    Day8
    安装出错
    安装步骤
    技术面试
    工作机会查找
    selenium 关于富文本的处理
    selenium查找动态的iframe的name
    eclipse项目debug方法
  • 原文地址:https://www.cnblogs.com/cglongge/p/9020497.html
Copyright © 2011-2022 走看看