【洛谷】【要再刷】P3375 【模板】KMP字符串匹配

从网上找的板子
评论区巨巨的题解贼好

#include 
using namespace std;
#define what(x) cout << #x << " is " << x << endl;

vector<int> getNxt(string s2)
{
    vector<int> nxt(s2.length());
    nxt[0] = 0;  // 模式串的第一个字符的最长前缀串长度为0
    for (int i = 1, j = 0; i < s2.length(); ++i) {
        while (j > 0 && s2[i] != s2[j])
            j = nxt[j-1];
        if (s2[i] == s2[j]) ++j;
        nxt[i] = j;
    }
    return nxt;
}

int ikmp (string s1, string s2, vector<int> &nxt)
{
    if (s1.empty()) return -1;
    int pos = 0;
    for (int i = 0, j = 0; i < s1.length(); ++i) {
        while (j > 0 && s1[i] != s2[j]) j = nxt[j-1];
        if (s1[i] == s2[j]) ++j;
        if (j == s2.length()) {
            return i-s2.length()+1;
        }
        //what(i);what(j);cout << endl;
    }
    return -1;
}

int main()
{
    string s1, s2;
    while (cin >> s1 >> s2) {
        vector<int> nxt = getNxt(s2);
        for (int i = 0, pos = 0, tmp = 0; i < s1.length(); ++i) {
            pos = ikmp(s1.substr(tmp), s2, nxt) + 1;
            if (pos == 0) break;
            tmp += pos;
            cout << tmp << endl;
        }

        for (auto i : nxt)
            cout << i << ' ';
        cout << endl;
    }
    return 0;
}

你可能感兴趣的:(洛谷)