北大1961题
来源:互联网 发布:生死狙击刷枪刷枪软件 编辑:程序博客网 时间:2024/04/30 12:53
题目连接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1961
1,KMP算法本质是个迭代算法,最神奇的地方在于next函数。
2,其中next[j] = k代表的意思是如果pad与某个串匹配的过程中在第j位失配,下一次应该保持主串指针不动,让pad在指针k处的值代替原先的在指针i处的值开始继续比较。这个主串当然可以是与pad相同的串。形式化的说明就是:p0 p1……pk-1 = pj-k+1 pj-k+2 ……pj-1,且不存在k`>k满足上式。
3,从2的说明中经过一个不太容易理解(多看两边就能明白的)的求取next的迭代过程,迭代方程如下:
next[0] = -1
next[i+1] = next[i] + 1(p next[i] == pi)
next[i+1] = next[i`] + 1(p next[i`] == pi)
说明:在求pad的next函数时实际将pad的最后的/n也当做了一个字符。
4,换个角度去解释2中的next[i] = k,能得到pad的一些性质,next[i] = k 表示在pad中第i个位置失配时,应该将pad右移直到第k位取代第i位与母串当前指针处的字符进行比较。此时如果把移出的串作为一个整体,其长度设为slen,pad的长度设为tlen,如果tlen - slen能被slen整除表明移出的串是个最小基本串,整个pad是连续tlen/slen个基本串的组合,如果tlen - slen不能被slen整除那么剩余的串是个特殊前缀,之所以特殊是因为末尾有一个同样长度的串和他相等,并且这个长度是最大的。
5,这个题目实质就是要求一个串中是否由多个基本串构成如果有求出基本串的重复次数,只不过这个题稍微作了一些变化,给定一个串让求其前缀基本串重复次数大于1的情况,循环不就行了吗
#include <iostream>
using namespace std;
#define MAX 1000000
char str[MAX+1];
int len;
int next[MAX+1];
int main()
{
freopen("in.txt","r",stdin);
int i,j,t,c;
c = 1;
while(cin >> len && len)
{
cin >> str;
next[0] = j = -1;
i = 0;
while(i < len)
{
if(j == -1 || str[i] == str[j])
{
++i,++j;
next[i] = j;//实际会把/n也看做一个字符
}
else
j = next[j];
}
printf("Test case #%d/n",c++);
for(i = 2;i <= len;++i)
{
t = i - next[i];
if(i % t == 0 && i / t > 1)
printf("%d %d/n",i,i/t);
}
printf("/n");
}
return 0;
}
- 北大1961题
- 北大1002题
- 北大1503题
- 北大1519题
- 北大1517题
- 北大1068题
- 北大2039题
- 北大1484题
- 北大2590题
- 北大2608题
- 北大1047题
- 北大1102题
- 北大1316题
- 北大3268题
- 北大2394题
- 北大2895题
- 北大2109题
- 北大1328题
- 2009年10大战略性技术
- ko
- Linux 进程控制
- 微软IE8 正式版发布 使用体验(组图)
- 在 ASP.NET 中设置 html 文件的访问验证
- 北大1961题
- 《利维坦》:人性(1)
- 台湾清华大学彭明辉教授《生命是一连串长期而持续的累积》
- C#试题
- 春巧
- 浮点数在计算机中存储方式(zz )
- 网管应该知道的命令
- Log4cxx中多用户的解决方法之一
- Java中的23种设计模式