现在的位置: 首页 > 综合 > 正文

[算法运用]KMP实战演练

2013年05月30日 ⁄ 综合 ⁄ 共 820字 ⁄ 字号 评论关闭

看完花名,滚来写总结了。( >﹏<。)~呜呜....

题目:HDU1358

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1358

大意:求字符串子串最大分割自我循环次数。(表达的不好)

解题:  第一念头想着用KMP两层循环切割字符串,第一层处理原串,第二层处理模式串。

然后费了好大的劲写了出来,结果,结果超时了 (┬_┬),(喂,这是理所应当的吧)。

没办法只好搜答案,发现只要运用next数组就可以解决了 (* ̄▽ ̄)y !

同时发现了自己的一个误区,原本以为next数组的值小于等于 slen/2,但实际上只要小于 slen就可以了。

同时可以发现,当next[slen]>slen/2,前缀与后缀有重叠的部分,通过观察可以发现答案与其的关系,至于原理目前未想通,(´Д`)

代码:

  1. 原来单单用next数组就可以算出字符串的自我循环次数了。 (* ̄︶ ̄)y 
  2. 以上

#include <algorithm>
using namespace std;

char s[1000000];
int nextp[1000000];
void getnextp(char p[], int nextp[])
{
    int i = 0, j = -1, l = strlen(p);
    nextp[0] = -1;
    while(i<l)
    {
        if(j==-1||p[i]==p[j])
        {
            i++;
            j++;
            nextp[i] = j;
        }
        else
            j = nextp[j];
    }
}
int main()
{
    int i, n,out = 0;
    while (scanf("%d", &n),n)
    {
        getchar();
        gets(s);
        printf("Test case #%d\n", ++out);
        getnextp(s,nextp);
        for(i=2;i<=n;i++)
        {
            if(!(i%(i-nextp[i]))&&i/(i-nextp[i])!=1)
                printf("%d %d\n", i, i/(i-nextp[i]));
        }
        printf("\n");
    }
}

抱歉!评论已关闭.