P8195 [传智杯 #4 决赛] 小智的疑惑 ----- 字符串匹配、KMP算法优化next数组

题目描述

传智专修学院给了小智一个仅包含小写字母的字符串 ss,他想知道,里面出现了多少次子串 chuanzhi 呢。

我们称一个字符串 tt 是 ss 的子串,当且仅当将 ss 的开头若干个(可以为 0 个)连续字符和结尾若干个(可以为 0 个)连续字符删去后,剩下的字符串和 tt 相同。例如,我们称 ab 是 abc 的子串,但 ac 不是 abc 的子串。

输入格式

输入只有一行一个字符串,表示字符串 ss。

输出格式

输出一行一个整数表示答案。

输入输出样例

输入 #1
welcometochuanzhicupchuanzhi
输出 #1
2

说明/提示

数据规模与约定

对于全部的测试点,保证 1 \leq |s| \leq 4 \times 10^51s4×105,|s|s∣ 表示 ss 的长度,且 ss 中只有小写字母。

KMP算法(虽然本题字符串为题目给出 所以并没有效果)

#include <iostream>
#include <string>
#include <vector>

using namespace std;
int main(){
    vector<int> next;
    string s;
    string cz = "chuanzhi";
    cin >> s;
    int n, m;
    int count = 0;
    n = s.size();
    m = cz.size();

    int x = 1;
    int now = 0;

    next.push_back(0);
    while (x < m) {
        if (cz[now] == cz[x]) {
            now++;
            x++;
            next.push_back(now);
        }
        else if (now) now = next[now - 1];
        else next.push_back(0), x++;
    }

    /*while (m--) {
        cout << next[m] << " / ";
    }*/

    int i = 0, j = 0;
    while (i < n) {
        if (s[i] == cz[j]) {
            i++;
            j++;
        }
        else if (j) j = next[j-1];
        else {
            i++;
        }
        if (j == 7) {
            count++;
            j = next[j-1];
        }
    }
    cout << count;
}

 

博主的KMP详解连接:👉KMP 算法理解与掌握 边学边写 ------字符串匹配问题(父串中寻找字串) - slowlydance2me - 博客园 (cnblogs.com)

posted @ 2022-11-20 19:52  slowlydance2me  阅读(52)  评论(0编辑  收藏  举报