KMP算法

单次匹配——输出第一次的首位置

/*
-------------------------------------------------
   Author:       wry
   date:         2022/2/25 15:20
   Description:  String_2
-------------------------------------------------
*/

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1000+10;

int NextTable[MAXN];

void GetNextTable(string pattern) {
    int m = pattern.size();
    int j = 0;
    NextTable[j] = -1;
    int t = NextTable[j];
    while (j<m) {
        if (t==-1 || pattern[t]==pattern[j]) {
            t++;
            j++;
            NextTable[j] = t;
        }
        else {
            t = NextTable[t];
        }
    }
}

int KMP (string text,string pattern) {
    GetNextTable(pattern);
    int n = text.size();
    int m = pattern.size();
    int i = 0;
    int j = 0;
    while (i<n && j<m) {
        if (j==-1 || text[i]==pattern[j]) {
            i++;
            j++;
        }
        else {
            j = NextTable[j];
        }
    }
    //当pattern到了最后一个字符匹配成功时,再++,即j==m
    if (j==m) {
        return i-j;
    }
    else {
        return -1;
    }
}

int main() {
    string text,pattern;
    cin >> text >> pattern;
    int position = KMP(text,pattern);    //返回下标
    cout << position << endl;
    return 0;
}

1 2 1 2 3 1 2 3 1 2 2 1 2

               1 2 3 1 2

对于12313的next

next[0] = -1

j=0,t=-1,j++,t++,next[1]= 0

j=1,t=0,t=next[t]= -1

j=1,t=-1,j++,t++,next[2]= 0

j=2,t=0,t=next[t]= -1

j=2,t=-1,j++,t++,next[3]= 0

j=3,t=0,pattern[j]==pattern[t],j++,t++,next[4]= 1

 

多次匹配——允许、不允许重复匹配,返回成功次数

/*
-------------------------------------------------
   Author:       wry
   date:         2022/2/25 15:20
   Description:  String_2
-------------------------------------------------
*/

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1000+10;

int NextTable[MAXN];

void GetNextTable(string pattern) {
    int m = pattern.size();
    int j = 0;
    NextTable[j] = -1;
    int t = NextTable[j];
    while (j<m) {
        if (t==-1 || pattern[t]==pattern[j]) {
            t++;
            j++;
            NextTable[j] = t;
        }
        else {
            t = NextTable[t];
        }
    }
}

int KMP (string text,string pattern) {
    GetNextTable(pattern);
    int n = text.size();
    int m = pattern.size();
    int i = 0;
    int j = 0;
    int number = 0;
    while (i<n && j<m) {
        if (j==-1 || text[i]==pattern[j]) {
            i++;
            j++;
        }
        else {
            j = NextTable[j];
        }
        //多次匹配
        //当pattern到了最后一个字符匹配成功时,再++,即j==m
        if (j==m) {
            number++;
            //j = NextTable[j];    //允许重复匹配
            j = 0;     //不允许重复匹配
        }
    }

    return number;
}

int main() {
    string text,pattern;
    cin >> text >> pattern;
    int number =KMP(text,pattern);
    cout << number << endl;
    return 0;
}

 

posted @ 2022-02-25 16:26  火星架构师  阅读(27)  评论(0)    收藏  举报