zoukankan      html  css  js  c++  java
  • poj2406 Power Strings 【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.

    题意:

    找一个串最短循环节

    思路:

    又是一个next数组的应用 不会写 查了资料的

    我们先假设到达位置 i-1 的时候,字符串循环了(到i-1完毕),那么如果到第i个字符的时候,失配了,根据next数组的求法,我们是不是得回溯?

    然而回溯的话,由于字符串是循环的了(这个是假定的),next[i] 是不是指向上一个循环节的后面一个字符呢??

    是的,上一个循环节的末尾是 next[i]-1 ,然后现在循环节的末尾是 i-1 ,然么循环节的长度是多少呢?

    所以,我们有 (i - 1) - ( next[i] - 1 ) = i - next[i]  就是循环节的长度(假设循环成立的条件下),但是我们怎么知道这个循环到底成立吗?

    现在我们已经假设了 0————i-1 循环了,那么我们就一共有i 个字符了,如果有 i % ( i - next[i] ) == 0,总的字符数刚好是循环节的倍数,那么说明这个循环是成立的。

    注意还有一点,如果 next[i] == 0,即使符合上述等式,这也不是循环的,举个反例

    0   1    2   3   4   5

    a    b   c   a   b   d

    -1   0   0   0   1   2 

    下标为1,2,3的next值均为0,那么 i%(i-next【i】)=i%i==0,但是这个并不是循环。

     

    如果对于next数组中的 i, 符合 i % ( i - next[i] ) == 0 && next[i] != 0 , 说明字符串循环,而且

    循环节长度为:   i - next[i]

    循环次数为:       i / ( i - next[i] )

    刚开始本来也不是很理解这个说的 以为要遍历算一下最大的

    其实应该算一下len的循环就可以了

     

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #define inf 0x3f3f3f3f
    
    using namespace std;
    
    char str[1000005];
    int nnext[1000005];
    
    void getnext()
    {
        int i = 0, j = -1;
        nnext[0] = -1;
        int len = strlen(str);
        while(i < len){
            if(j == -1 || str[i] == str[j]){
                i++;
                j++;
                nnext[i] = j;
            }
            else{
                j = nnext[j];
            }
        }
    }
    
    int main()
    {
        while(scanf("%s", str) && str[0] != '.'){
            memset(nnext, 0, sizeof(nnext));
            getnext();
            int ans = 1;
            int len = strlen(str);
            if(nnext[len] != 0 && !(len % (len - nnext[len]))){
                ans = len / (len - nnext[len]);
            }
            /*for(int i = 0; i < strlen(str); i++){
                if(nnext[i] != 0 && !(i % (i - nnext[i]))){
                    ans = max(ans, i / (i - nnext[i]));
                }
            }*/
            printf("%d
    ", ans);
        }
    	return 0;
    }
    



  • 相关阅读:
    tuple 元组及字典dict
    day 49 css属性补充浮动 属性定位 抽屉作业
    day48 选择器(基本、层级 、属性) css属性
    day47 列表 表单 css初识
    day 46 http和html
    day 45索引
    day 44 练习题讲解 多表查询
    day 40 多表查询 子查询
    day39 表之间的关联关系、 补充 表操作总结 where 、group by、
    day38 数据类型 约束条件
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9643433.html
Copyright © 2011-2022 走看看