KMP poj 2406 Power Strings 字符串的幂

题意:

    给定两个字符串a和b,定义式子:a*b表示两个字符串的连接,例如:a = "abc", b = "def" 则:a*b = "abcdef"。如果将连乘看成乘法,则按照普遍的方法一个非负整数的幂表示如下: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).

输入:

    输入字符串S每组样例一行,S为可打印字符.S长度在1~1000000之间,最后一组数据后为“.”表示结束。

输出:

   每个S输出最大的n满足:S = a^n,其中a为任意字符串。


分析:

    题目大意:给出一个字符串,求出他的最小重复单元是什么,进而再求出重复次数,例如:“aaaa”最小重复单元是“a”重复次数是4;

解题思路:设字符串S = “abcabc”求其next数组:

S:       a  b  c  a  b  c

next[j]: -1 0  0  0  1  2  3

在这里为了计算要多算出一位,那么可能成为最小重复单元的长度可由下面的规则确定:

(1)若2*next[len] < len 则最小重复单元长度为len那么他重复次数为1

(2)若2*next[len] > len 则:

1>:如果len%(len-next[len]) == 0则最小重复单元长度为len - next[len],那么其重复次数为len/(len-next[len]).

2>:如果len%(len - next[len]) != 0 则最小重复单元长度为:len,那么其重复次数为1

好好揣摩以上两点!

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int MAXN = 1000010;

int next[MAXN];

void Get_next(char* str)
{
    int i = 0, j = -1;
    next[0] = -1;
    int len = strlen(str);
    while(i < len)
    {
        if(j == -1 || str[i] == str[j])
        {
            ++i;
            ++j;
            next[i] = j;
        }
        else
            j = next[j];
    }
}


int main()
{
    char str[MAXN];
    while(~scanf("%s", str))
    {
        if(str[0] == '.')
            break;
        Get_next(str);
        int len = strlen(str);
        if(2*next[len] < len)
            cout<<"1"<<endl;
        else
        {
            if(len % (len - next[len]) == 0)
                cout<<len/(len-next[len])<<endl;
            else
                cout<<"1"<<endl;
        }
    }
    return 0;
}


你可能感兴趣的:(KMP)