KMP 算法

KMP 算法查找在文本中是否出现过某个字符或串。算法核心在于是状态转移,利用以前的信息去掉多余的比较。

example: 当一个串ababce在和ababd匹配到ababc的时候失败了,现在要比较的是c(abce中的c)和a(abab中的第二个a)比较。

为什么?

因为abab重复出现c出匹配失败,那么至少ab是匹配成功的。就是说长度为4的模式串的前缀等于后缀的最大长度为2.

所以我们可以得到这样的一个失败函数:(对于模式串来说)(前缀不能等于已经匹配了的字符长度)

i = 0, next = 0;   //已经匹配了0个字符,前缀等于后缀的最大长度是0

i = 1, next = 0;   //已经匹配了1个字符,前缀等于后缀的最大长度是0(也可以说正在匹配第i个字符)


所以用递推地方法,如果i位置的字符等于已经匹配的字符的最大长度的下一个字符,我们就得到了已经匹配了i+1个字符的

最大匹配长度;否则,沿着失败边走。

举个例子:

对abababa求失败函数:

初始化next[0] = next[1] = 0;   //已经匹配了0个和1个字符的失败函数都是0

abababa

00

i= 1;正在匹配 b 字符,失败next[2] = 0;

i = 2 正在匹配a字符,成功,next[3] = 1;

i = 3 正在匹配b字符,成功,next[4] = 2;

i = 4 正在匹配a字符,成功,next[5] = 3;

i = 5 正在匹配b字符,成功,next[6] = 4;

i = 6 正在匹配a字符,成功,next[7] = 5;

char s[10000];
char p[1000];
int next[1005];
void get_fail()
{
    next[0] = next[1] = 0;
    int j;
    for (int i = 1; p[i]; i ++)   //正在匹配第i个字符(已经匹配了i个字符)
    {
        j = next[i];
        while (j && p[i] != p[j]) j = next[j]; //匹配失败沿着匹配边走
        next[i+1] = p[i] == p[j] ? j+1:0;  //匹配成功,则多匹配一个字符
    }
}

int KMP()
{
    int len = strlen(p);
    int j = 0;
    for (int i = 0; s[i]; i ++) //正在匹配第i个字符
    {
        while (j && s[i] != p[j]) j = next[j];//匹配失败沿着匹配边走
        if(s[i] == p[j]) j ++;
        if (j == len) return 1;
    }
return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值