KMP算法(Java)

在进行KMP查找之前先要求出目标字符串的next数组(当前位置子串的前缀子串和后缀子串的最长公共子串),然后进行KMP查找。

如图:

 

Java代码实现KMP算法:

package Algorithm.kmp;

import java.util.Arrays;

public class KMPAlgorithm {
    public static void main(String[] args) {
        String str1 = "BBC ABCDAB ABCDABCDABDE";
        String str2 = "ABCDABD";

        int[] next = kmpNext(str2);
        System.out.println(Arrays.toString(next));

        int index = kmpSerach(str1,str2,next);
        System.out.println(index);

    }

    /**
     * KMP匹配算法
     * @param str1 源字符串
     * @param str2 目标字符串
     * @param next 目标字符串的部分匹配值表
     * @return 返回-1则说明没有匹配成功,否则返回第一个匹配的位置
     */
    public static int kmpSerach( String str1, String str2, int[] next ) {
        for ( int i = 0, j = 0; i < str1.length(); i++ ) {
            //KMP算法核心点:处理 str1.charAt(i) != str2.charAt(j)
            while ( j > 0 && str1.charAt(i) != str2.charAt(j) ) {
                j = next[j - 1];
            }

            if ( str1.charAt(i) == str2.charAt(j) ) {
                j++;
            }

            if ( j == str2.length() ) {
                return i - j + 1;
            }
        }
        return -1;
    }

    /**
     * 获取到一个子串的部分匹配值表
     * @param dest 目标字符串
     * @return 返回一个整形数组,里面的数字代表当前子串的前缀子串和后缀子串的最长公共串
     */
    public static int[] kmpNext(String dest) {
        //创建一个next数组来保存部分匹配值
        int[] next = new int[dest.length()];

        next[0] = 0;//字符串长度为1时,它的部分匹配值为0

        for ( int i = 1, j = 0; i < dest.length(); i++ ) {

            while ( j > 0 && dest.charAt(i) != dest.charAt(j) ) {
                j = next[j - 1]; //KMP算法的核心
            }

            if ( dest.charAt(i) == dest.charAt(j) ) {
                j++;
            }
            next[i] = j;
        }
        return next;
    }
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值