• hdu 1358 KMP的应用


    网上好多说得不够清楚,不过真正理解了KMP的next数组的含义,一点就通了。非优化的next数组的含义是:next[i]=k表示模式串下标为i的字符的前k个字符与开头的前k个字符相等,那么从0到i-1的模式串必然是循环的,循环节为从0到next[i] - (2 * next[i] - i),其中 2 * next[i] - i表示的是从后往前的部分与从前往后的部分相交的长度。

    /*
    * hdu1358/linux.cpp
    * Created on: 2011-8-29
    * Author : ben
    */
    #include
    <cstdio>
    #include
    <cstdlib>
    #include
    <cstring>
    #include
    <cmath>
    #include
    <algorithm>
    using namespace std;

    #define MAXN 1000005
    int N;
    char str[MAXN];
    int nextval[MAXN];

    void work();
    int main() {
    #ifndef ONLINE_JUDGE
    freopen(
    "data.in", "r", stdin);
    #endif
    work();
    return 0;
    }

    void get_nextval() {
    int i = 0, j = -1;
    int parlen = N;
    char *pattern = str;
    nextval[
    0] = -1;
    while (i < parlen) {
    if (j < 0 || pattern[i] == pattern[j]) {
    i
    ++;
    j
    ++;
    if (pattern[i] != pattern[j]) {
    nextval[i]
    = j;
    }
    else {
    nextval[i]
    = nextval[j];
    }
    }
    else {
    j
    = nextval[j];
    }
    }
    }

    void get_next() {
    int i = 0, j = -1;
    int parlen = N;
    char *pattern = str;
    nextval[
    0] = -1;
    while (i <= parlen) {
    if (j == -1 || pattern[i] == pattern[j]) {
    i
    ++;
    j
    ++;
    nextval[i]
    = j;
    }
    else {
    j
    = nextval[j];
    }
    }
    }

    void work() {
    int T = 0, tmp;
    while (scanf("%d", &N) == 1 && N > 0) {
    scanf(
    "%s", str);
    get_next();
    printf(
    "Test case #%d\n", ++T);
    for (int i = 2; i <= N; i++) {
    tmp
    = i - nextval[i];
    if (i % tmp == 0 && i / tmp > 1) {
    printf(
    "%d %d\n", i, i / tmp);
    }
    }
    putchar(
    '\n');
    }
    }
  • 相关阅读:
    题解 CF700E Cool Slogans
    题解 LOJ2065 「SDOI2016」模式字符串
    以guest账号无密码访问设置
    共享
    计算机的C$共享在哪里
    网卡工作原理
    iperf网络测试
    Jmeter安装与使用(压测)
    压测工具使用(vegeta)
    Alertmanager 安装(k8s报警)
  • 原文地址:https://www.cnblogs.com/moonbay/p/2158446.html
Copyright © 2020-2023  润新知