KMP算法简介(附模板代码)

目录

KMP算法介绍:

KMP算法的详细步骤:

kmp算法总结:

kmp模板代码:


KMP算法介绍:

KMP(Knuth-Morris-Pratt)算法是一种字符串匹配算法,用于在一个文本字符串中搜索一个模式字符串的出现位置。它的名字来源于发明者的姓氏。

KMP算法的主要思想是利用已经匹配过的信息来避免不必要的比较,从而提高匹配的效率。它通过构建一个部分匹配表(Partial Match Table)来实现这一点。

部分匹配表是模式字符串自身的一种自我匹配表,它记录了模式字符串中每个前缀子串的最长相同前缀后缀长度。这些信息告诉算法在匹配过程中,当出现不匹配的字符时,可以跳过一些比较操作,直接将模式字符串向右移动到一个新的位置,从而减少比较的次数。

KMP算法的详细步骤:

1. 首先,构建模式字符串的部分匹配表。遍历模式字符串,对于每个位置i,计算模式字符串的前缀子串[0, i]的最长相同前缀后缀长度,并将这个长度记录在部分匹配表中的位置i上。

2. 在匹配过程中,维护两个指针:一个指向文本字符串中当前要匹配的字符,另一个指向模式字符串中当前要匹配的字符。

3. 开始匹配过程。将两个指针初始化为0,然后从左到右遍历文本字符串中的字符。

4. 如果当前字符匹配成功,将两个指针都向右移动一位,继续比较下一个字符。

5. 如果当前字符不匹配,根据部分匹配表中的信息,将模式字符串向右移动一定的距离,然后继续比较当前字符和模式字符串中对应位置的字符。

   - 如果部分匹配表中对应位置的值为0,表示无法再向右移动,将模式字符串的指针移动到下一个位置,继续匹配。

   - 如果部分匹配表中对应位置的值大于0,表示可以向右移动一定的距离。

6. 重复步骤4和步骤5,直到匹配成功或者遍历完整个文本字符串。

kmp算法总结:

KMP算法的核心是在匹配过程中,根据部分匹配表的信息来确定模式字符串的移动距离,从而减少不必要的比较操作。这种优化使得KMP算法的时间复杂度为O(n+m),其中n是文本字符串的长度,m是模式字符串的长度。相比于朴素的字符串匹配算法,KMP算法具有更高的效率。

kmp模板代码:

#include
#include
using namespace std;

const int N=1e5+6; // 模式字符串的最大长度
const int M=1e6+6; // 文本字符串的最大长度

int n,m; // 模式字符串和文本字符串的长度
char s[M],p[N]; // 用于存储文本字符串和模式字符串的数组
int ne[N]; // 用于存储模式字符串的next数组

int main(){
    cin>>n>>p+1>>m>>s+1; // 输入模式字符串和文本字符串的长度,以及模式字符串和文本字符串的内容
    
    // 预处理步骤:构建模式字符串的next数组
    for(int i=2,j=0;i<=n;i++){
        while(j && p[i]!=p[j+1]) j=ne[j];
        if(p[i]==p[j+1]) j++;
        ne[i]=j;
    }
    
    // 在文本字符串中搜索模式字符串的出现位置
    for(int i=1,j=0;i<=m;i++){
        while(j && s[i]!=p[j+1]) j=ne[j];
        if(s[i]==p[j+1]) j++;
        if(j==n){
            printf("%d ",i-n); // 打印每个模式出现在文本中的起始位置
            j=ne[j];
        }
    }
    return 0;
}

你可能感兴趣的:(c++,kmp算法)