POJ2752 Seek the Name, Seek the Fame 题解 KMP算法

题目链接:http://poj.org/problem?id=2752
题目大意:给你一个字符串 \(S\) ,如果它的一个前缀同时也是它的后缀,则输出这个前缀(后缀)的长度。
题目分析:next函数的一个应用。我们设 \(S\) 串的长度为 \(n\) ,则我们首先设 \(j=n-1\) ,然后只要 \(nxt[j] != -1\) ,那么 \(j+1\) 就是一个答案,循环使 \(j=nxt[j]\) 。
实现代码如下:

#include <iostream>
#include <string>
using namespace std;
const int maxn = 404000;

int m, nxt[maxn];
string t;
char ch[maxn];

void cal_next() {
    m = t.length();
    for (int i = 0, j = -1; i < m; i ++) {
        while (j != -1 && t[j+1] != t[i]) j = nxt[j];
        nxt[i] = (j+1 < i && t[j+1] == t[i]) ? ++j : -1;
    }
}

bool output(int j) {
    if (j == -1) return false;
    if (output(nxt[j])) cout << " ";
    cout << j + 1;
    return true;
}

int main() {
    while (cin >> t) {
        cal_next();
        output(m-1);
        cout << endl;
    }
    return 0;
}

作者:zifeiy

posted @ 2019-11-04 20:19  codedecision  阅读(78)  评论(0编辑  收藏  举报