KMP算法

本文用于自己观看回忆KMP算法

KMP算法简介

1.可在一个主文本字符串S内查找一个词W的出现位置。
2.其流程大致分为两步,第一为构造next数组。第二部分利用next数组来实现模式串w与S的匹配,找到字符串S中w第一次出现的位置(索引)。

Next数组

  1. 首先Next数组元素定义为,该字符之前的字符串中具有相同前缀后缀的长度为多少。例: 给定S串“DABCDABDE”,设他的next数组 P,P数组所存的值应该依次为[-1,0,0,0,0,1,2,3,1]。

    其中,E对应的next 值为1(即字符E之前的字符串“DABCDABD”中有长度为1的相同前缀和后缀)。

  2. Next数组代码

void GetNext(char* p,int next[])  
{  
    int pLen = strlen(p);  
    next[0] = -1;  
    int k = -1;  
    int j = 0;  
    while (j < pLen - 1)  
    {  
        //p[k]表示前缀,p[j]表示后缀  
        if (k == -1 || p[j] == p[k])   
        {  
            ++k;  
            ++j;  
            next[j] = k;  
        }  
        else   
        {  
            k = next[k];  
        }  
    }  
}  

因为next数组元素含义的定义,所以当P[i] == P[k]时,先使得k++,i++(k在这里可以表示为匹配的最长前缀后缀长度),再使得next[j] = k;

当P[j] != P[k]时,让P[next[k]]再与P[j]尝试匹配(当next[k]!=0时,P[next[k]-1] ==p[j-1]),直到匹配P[j]成功,或者是k=-1,匹配失败。放弃继续匹配P[j],通过j++,k++。开始匹配p[j+1],同时next[j+1]设为0,表示0-j的字串最长相同前缀后缀长度为0;

例题:Leetcode 1392最长快乐前缀.

模式串匹配

模式串匹配时,匹配成功一个字符和匹配失败一个字符时,和构造next数组时处理方法相似。代码也都相似。

int KmpSearch(char* s, char* p)  
{  
    int i = 0;  
    int j = 0;  
    int sLen = strlen(s);  
    int pLen = strlen(p);  
    while (i < sLen && j < pLen)  
    {  
        //①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++      
        if (j == -1 || s[i] == p[j])  
        {  
            i++;  
            j++;  
        }  
        else  
        {  
            //②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]      
            //next[j]即为j所对应的next值        
            j = next[j];  
        }  
    }  
    if (j == pLen)  
        return i - j;  
    else  
        return -1;  
}  

Leetcode 214最短回文串.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值