KMP算法

主要思路

  找出模式串的next数字,然后将主串和模式串比较,匹配时则继续,不匹配时则模式串根据next数组回溯,直到模式串完全匹配,此时主串指针的位置减去模式串指针的位置即为主串中模式串的起始位置;模式串没有完全匹配则表示主串中不存在该模式串。

求模式串的next数组

例子:

ABABA
-10012

  主要逻辑是P[ 0 ~ k-1 ] = P[ j-k ~ j-1 ]。因为k=0时,k-1<0表示k左边没有可以回溯的,所以next[0]总是等于-1。

image

private int[] getNext(char[] keys) {
    int[] next = new int[keys.length];
    next[0] = -1;
    int i = -1, j = 0;
    while (j < keys.length - 1) {
        // 当i=-1时依然表示没有可以再回溯的东西,所以直接将++j回溯的位置置为0。
        // keys[i]=keys[j]表示 0~i 和 j-i~j 相匹配,所以++j不匹配时的回溯位置自然就是++i。
        if (i == -1 || keys[i] == keys[j]) {
            next[++j] = ++i;
        } else {
            // keys[i]!=keys[j]时表示模式串需要回溯,因为之前已经求出了回溯的位置,
            // 所以直接通过先前求出的next数组获取回溯的位置
            i = next[i];
        }
    }
    return next;
}
求主串和模式串匹配的位置

  主要逻辑是将主串和模式串从头开始一一比较,如果相等则继续比较下一位字符,若不相等则根据next数组将模式串回溯,直到模式串全部匹配成功,则表示匹配成功。

private int getKeys(char[] str, char[] keys) {
    int i = 0, j = 0;
    // 首先获取模式串的next数组
    int[] next = getNext(keys);
    // 主串和模式串从头开始一一比较
    while (i < str.length && j < keys.length) {
        // 主串与模式串相等或者模式串回溯到-1时直接比较下一位
        if (j == -1 || str[i] == keys[j]) {
            i++;
            j++;
        } else {
            // 不匹配时回溯模式串
            j = next[j];
        }
    }
    // 模式串全部匹配成功
    if (j == keys.length) {
        // 返回主串中模式串的位置
        return i - j;
    }
    return -1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值