KMP(模板)

KMP算法

KMP算法是用来处理一对一的匹配的。

朴素的匹配算法,或者说暴力匹配法,就是将两个字符串从头比到尾,若是有一个不同,那么从下一位再开始比。这样太慢了。所以KMP算法的思想是,对匹配串本身先做一个处理,得到一个next数组。这个数组是做什么用的呢?next [j] = k,代表j之前的字符串中有最大长度为k 的相同前缀后缀。记录这个有什么用呢?对于ABCDABC这个串,如果我们匹配ABCDABTBCDABC这个长串,当匹配到第7个字符T的时候就不匹配了,我们就不用直接移到B开始再比一次,而是直接移到第5位来比较,岂不美哉?所以求出了next数组,KMP就完成了一大半。next数组也可以说是开始比较的位数。

计算next数组的方法是对于长度为n的匹配串,从0到n-1位依次求出前缀后缀最大匹配长度。

比如ABCDABD这个串:

KMP(模板)_第1张图片

(图片来源https://www.cnblogs.com/zhangtianq/p/5839909.html)

 

对于next的求法,记住next[j]=next[j-1]+1 这个式子 -->如果有字符匹配时 j 保存的最长前后缀与j-1次保存的有关

void getnext(char *ptr)//获取next数组 
{//记住当不匹配的时候 我们要找的是上一次完成匹配的情况下的最大匹配值
// 目的: 这样就不用把i回溯来匹配了,所以next的存储方式就出来了 

    int i,n,k;
    n=strlen(ptr);
    k=-1; 
    next[0]=-1;
    i=0;
    
    while(i

 

结合了《算法导论》和《数据结构》的思想;而在数据结构中,str[0]保存的是字符串的长度,最开始没想到而写错了,抱歉!

int kmp(char *a,char *b)//匹配ab两串,a为父串
{
    int i=0,j=0;
    int len1=strlen(a);
    int len2=strlen(b);
    getnext(b);
    while(i

 

    ABCDABTABCDABC
    ABCDABC
    0000123

把上面的样例放入程序动手模拟一下就可以明白大概了

 

这里next数组的作用就显现出来了。最后返回的是i-j,也就是说,是从i位置前面的第j位开始的,也就是上面说的,next数组也可以说是开始比较的位数。也就是说,在父串的i位比的时候已经是在比子串的第j位了。

一个完整的代码:

#include 
#include 
#include 
using namespace std;
const int N=100;
int next[100];
void getnext(char *ptr)
{

    int i,n,k;
    n=strlen(ptr);
    k=-1;
    next[0]=-1;
    i=0;
    while(i
借鉴:https://www.cnblogs.com/yjiyjige/p/3263858.html

 

 

你可能感兴趣的:(C++)