zoukankan      html  css  js  c++  java
  • POJ 2406 power strings KMP中next函数的应用

    Power Strings
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 23370   Accepted: 9811

    Description

    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
    
     
      1 /* 功能Function Description:     POJ-2406
      2    开发环境Environment:          DEV C++ 4.9.9.1
      3    技术特点Technique:
      4    版本Version:
      5    作者Author:                   可笑痴狂
      6    日期Date:                      20120813
      7    备注Notes:
      8    题意:
      9         找出字符串的最小循环周期从而算出最大循环次数
     10 */
     11 /*
     12 //代码一:-----简单枚举法
     13 #include<stdio.h>
     14 #include<string.h>
     15 char s[1000005];
     16 
     17 int main()
     18 {
     19     int i,len,k,j,flag;
     20     while(scanf("%s",s+1)&&s[1]!='.')
     21     {
     22         len=strlen(s+1);
     23     //    printf("%d\n%c",len,s[1]);
     24         for(i=1;i<=len;++i)
     25         {
     26             if(len%i)
     27                 continue;
     28             flag=1;
     29             for(k=1;flag&&k<=i;++k)
     30             {
     31                 for(j=2;j<=len/i;++j)
     32                 {
     33                     if(s[k]!=s[i*(j-1)+k])
     34                     {
     35                         flag=0;
     36                         break;
     37                     }
     38                 }
     39             }
     40             if(flag)
     41             {
     42                 printf("%d\n",len/i);
     43                 break;
     44             }
     45         }
     46     }
     47     return 0;
     48 }
     49 */
     50 
     51 //代码二:-------KMP算法中next函数的性质
     52 /*
     53     设Len是s的长度
     54     给出结论:
     55     如果len%(len-next[len])==0,则字符串中必存在最小循环节,且循环次数即为 len/(len-next[len])
     56     
     57     题目大意:给出一个字符串,求出是某个字符串的n次方
     58     解决:KMP找出字符串的循环节
     59     若有字符串ai...a(j+m),若next[len+1]=m(字符串从1开始),意味着从ai ...am 和 aj...a(j+m)相等,
     60     假设中间有相交部分(或者相交部分为0)aj....am,若总长度减去相交部分剩余的部分能被总长度整除,
     61     又因为  从ai ...am 和 aj...aj+m相等,所以除去相交部分剩余的的两段字符串相等,而且必定满足中间相交部分也能被起始字符串整除,依照这样,
     62     即可得出最小的循环节 
     63 
     64 */
     65 
     66 #include<stdio.h>
     67 #include<string.h>
     68 char s[1000005];
     69 int next[1000005];
     70 
     71 void get_next(int len)
     72 {
     73     int i,j;
     74     i=0;
     75     j=-1;
     76     next[0]=-1;
     77     while(i<len)
     78     {
     79         if(j==-1||s[i]==s[j])
     80         {
     81             ++i;
     82             ++j;
     83             next[i]=j;
     84         }
     85         else
     86             j=next[j];
     87     }
     88 
     89     /*
     90     while(i<len)              //改进算法---改进在某些情况下的缺陷  详见数据结构课本P84
     91     {
     92         if(j==-1||s[i]==s[j])
     93         {
     94             ++i;
     95             ++j;
     96             if(s[i]!=s[j])
     97                 next[i]=j;
     98             else
     99                 next[i]=next[j];
    100         }
    101         else
    102             j=next[j];
    103     }
    104     */
    105 }
    106 
    107 int main()
    108 {
    109     int i,len,k,j,flag;
    110     while(scanf("%s",s)&&s[0]!='.')
    111     {
    112         len=strlen(s);
    113         get_next(len);
    114         if(len%(len-next[len])==0)
    115             printf("%d\n",len/(len-next[len]));
    116         else
    117             printf("1\n");
    118     }
    119     return 0;
    120 }
     
    功不成,身已退
  • 相关阅读:
    三步完成自适应网页设计
    EasyUI DataGrid 修改每页显示数量的最大值&&导出Grid到Excel
    EasyUI DataGrid 实用例子(2015-05-22)
    C# 如何将List拆分成多个子集合
    EasyUI Tabs绑定右键
    微信支付-扫码支付备忘
    微信支付:模板消息实现过程备忘
    4、http协议之二
    1、套按字及http基础知识之一
    3、Web server 之httpd2.2 配置说明
  • 原文地址:https://www.cnblogs.com/dongsheng/p/2635951.html
Copyright © 2011-2022 走看看