| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 12620 | Accepted: 6198 |
Description
Input
Output
Sample Input
ababcababababcabab aaaaa
Sample Output
2 4 9 18 1 2 3 4 5
KMP 算法next数组的应用, 寻找所有可能的公共前后缀,我们先对整个串求一个next数组,(未优化的next数组相当于每个字符之前存在的最长的公共前后缀长度-1)
然后去“截”这个串,每次截的位置是next[len - 1],len是未截之前字符串长度,一开始为整个字符串长度
#include <map>
#include <set>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 400010;
char str[N];
int next[N];
int ans[N];
void get_next()
{
int len = strlen(str);
int j = 0, k = -1;
next[0] = -1;
while (j < len - 1)
{
if (k == - 1 || str[j] == str[k])
{
++k;
++j;
next[j] = k; //没有优化过的
// 优化
/*if (str[k] != str[j])
{
next[j] = k;
}
else
{
next[j] = next[k];
}*/
}
else
{
k = next[k];
}
}
}
int main()
{
while (~scanf("%s", str))
{
int cnt = 0;
int len_len = strlen(str);
str[len_len++] = '*';
str[len_len] = '\0';
int len = len_len;
get_next();
while(1)
{
if (next[len_len - 1] > 0)
{
ans[++cnt] = next[len_len - 1];
// for (int i = 0; i < next[len_len - 1]; ++i)
// {
// printf("%c", str[i]);
// }
// printf("\n");
len_len = next[len_len - 1] + 1;
continue;
}
break;
}
for (int i = cnt; i >= 1; --i)
{
printf("%d ", ans[i]);
}
printf("%d\n", len - 1);
}
return 0;
}POJ2752——Seek the Name, Seek the Fame
原文地址:http://blog.csdn.net/guard_mine/article/details/41256693