KMP 模版

#include <iostream>
#include <string>
#include <string.h>
using namespace std;
const int maxn = 1e5 + 5;
int s[maxn], t[maxn], Next[maxn];//ss 大 tt小
string tt, ss;
int tlen, slen;
void getNext() {
    int j, k;
    j = 0; k = -1; Next[0] = -1;
    while(j < tlen)
        if(k == -1 || tt[j] == tt[k])
            Next[++j] = ++k;
        else // 一旦失配回到Next[k]重新匹配,此时ss[0] - ss[k - 1] 与  tt[j - k + 1] - tt[j - 1] 相同
            k = Next[k];
}
int KMP_Index() {//查找第一次出现的位置
    int i = 0, j = 0;
    getNext();
    while(i < slen && j < tlen) {
        if(j == -1 || ss[i] == tt[j]) {
            i ++; j ++;
        }
        else
            j = Next[j];

    }
    if(j == tlen)
        return i - tlen;
    return -1;
}
int KMP_Count() {//查找次数
    int ans = 0;
    int i, j = 0;
    
    if(slen == 1 && tlen == 1) {
        if(ss[0] == tt[0]) return 1;
        return 0;
    }
    getNext();
    for (i = 0; i < slen; i ++) {
        while(j > 0 && ss[i] != tt[j])
            j = Next[j];
        if(ss[i] == tt[j])
            j ++;
        if(j == tlen) {
            ans ++; j = Next[j];
        }
    }
    return ans;
}
int main(int argc, const char * argv[]) {
    cin >> ss >> tt;
    tlen = (int)tt.length();
    slen = (int)ss.length();
    printf("%d\n%d", KMP_Index(), KMP_Count());
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/81235412
kmp