Kmp算法(java)

kmp算法用于解决字符串匹配的问题,典型例题力扣28.实现Strstr() 28. 实现 strStr() - 力扣(LeetCode) (leetcode-cn.com)

kmp算法的核心:在当前对字符串和子字符串检索的过程中,若出现了不匹配,充分利用已经匹配的部分

具体如何理解可以看字符串匹配的KMP算法 - 阮一峰的网络日志 (ruanyifeng.com)

kmp算法分为两个部分

①创建字符串的next数组

②在暴力算法的基础上通过next数组回溯 j 来减少时间复杂度

java代码实现

    public static int Kmp(String str1, String str2, int[] next) {  
        for(int i = 0, j = 0; i < str1.length(); i++) {
            while(j > 0 && str1.charAt(i) != str2.charAt(j)) {  //不匹配的情况下
                j = next[j -1];  //通过next数组回溯j
            }
            if(str1.charAt(i) == str2.charAt(j)) {  //匹配的情况下
                j++;
            }
            if(j == str2.length()) {   //匹配成功返回
                return i - j +1;
            }
        }
        return -1;  //匹配不成功返回-1
    }

Next数组

next数组作用:创建个与子字符串位数相同的数组,每个位置上储存截至当前位置前后缀最长共有元素长度。("前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。)

next数组有3种写法,

如字符串"ABCDABD"

写法1:0000120 表示截至当前位置的最长相等前后缀 (个人感觉代码实现最好理解的方法,本文用的此方法)

写法2:-1000012 在写法1基础上右移,第一位改为-1

写法3:0111123 第一位为0,其他看截至前一位的最长相等前后缀+1,(一般的数据结构教材用的是此方法,考试手写也大多是次方法,但个人感觉在代码实现上并不好用)

创建Next数组代码实现(java)

①初始化next数组

②前后缀不相同的情况:j重复回退j=next[j-1],直到j==0或前后缀相同

③前后缀相同情况:j++

④给next数组赋值next[i]=j

public static int[] CreatNext(String str) {
        int[] next = new int[str.length()];
        next[0] = 0;
        for(int i = 1, j = 0; i < str.length(); i++) {
            while(j > 0 && str.charAt(i) != str.charAt(j)) {
                j = next[j - 1];
            }
            if(str.charAt(i) == str.charAt(j)) {
                j++;
            }
            next[i] = j;
        }
        return next;
    }

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KMP算法(Knuth-Morris-Pratt算法)是一种字符串匹配算法,用于在一个主串中查找一个模式串的出现位置。它的核心思想是利用已经匹配过的部分信息,尽量减少不必要的比较次数,从而提高匹配效率。 KMP算法的实现主要包括两个步骤:构建next数组和进行匹配。 1. 构建next数组: - 首先,我们需要定义一个next数组,用于存储模式串中每个位置的最长公共前后缀长度。 - 然后,从模式串的第二个字符开始,依次计算每个位置的最长公共前后缀长度。 - 最后,将计算得到的最长公共前后缀长度填入next数组中。 2. 进行匹配: - 在匹配过程中,我们需要维护两个指针:主串指针i和模式串指针j。 - 当主串和模式串的当前字符匹配时,i和j同时向后移动一位。 - 当主串和模式串的当前字符不匹配时,根据next数组的值调整模式串指针j的位置。 - 如果j等于模式串的长度,表示匹配成功,返回主串中匹配的起始位置。 下面是KMP算法Java实现示例: ```java public class KMP { public static int kmp(String text, String pattern) { int[] next = getNext(pattern); int i = 0, j = 0; while (i < text.length() && j < pattern.length()) { if (j == -1 || text.charAt(i) == pattern.charAt(j)) { i++; j++; } else { j = next[j]; } } if (j == pattern.length()) { return i - j; } else { return -1; } } private static int[] getNext(String pattern) { int[] next = new int[pattern.length()]; next[0] = -1; int i = 0, j = -1; while (i < pattern.length() - 1) { if (j == -1 || pattern.charAt(i) == pattern.charAt(j)) { i++; j++; next[i] = j; } else { j = next[j]; } } return next; } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值