KMP算法

本文详细介绍KMP算法的工作原理及其实现过程,通过实例演示如何构建next数组并进行字符串匹配,适用于初学者掌握快速字符串匹配技巧。

KMP算法

简介

KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)

先来了解一下前缀后缀的概念。”Happy”的前缀集合为{“H”, “Ha”, “Hap”, “Happ”},同理,”Happy”的后缀集合为{“appy”,”ppy”, “py”, “y”},注意的字符串本身既不是属于前缀集合也不属于后缀集合。

KMP算法中,最重要的是理解next[]数组是如何形成的。

next[]数组元素中的值为:字符串的前缀集合与后缀集合的交集中最长元素的长度。

这里写图片描述

举几个例子说明一下。
比如字符串”aba”,因为这个”aba”这个字符的前缀集合与后缀集合中,相等的并且最长的元素长度为1。

例如字符串”ababab”,计算一下该字符串的value。
前缀集合中存在字符串”abab”,后缀集合中也存在字符串”abab”,即该字符串的value为4。
在该字符串中,前缀集合中的最长元素为”ababa”,后缀集合中最长的元素为”babab”,显然这两个字符串是不相等的,所以该字符串的value为4。
剩下的以此类推。

为了编程的方便,我们把value的值向后移动一个位置,并设置第一个值为-1。

这里写图片描述

这里附上java代码:

public static void getNext(char[] p, int[] next)
    {
        next[0] = -1;
        int i = 0, j = -1;

        while (i < p.length - 1)
        {
            if (j == -1 || p[i] == p[j])
            {
                ++i;
                ++j;
                next[i] = j;
            }   
            else
                j = next[j];
        }
    }

求解好next[]数组后,第二步就需要依靠next[]数组,来进行串匹配。

public static int KMP(char[] t, char[] p, int[] next) 
    {
        int i = 0; 
        int j = 0;

        while (i < t.length  && j < p.length )
        {
            if (j == -1 || t[i] == p[j]) 
            {
                    i++;
                    j++;
            }
            else 
                    j = next[j];
            }

        if (j == p.length)
           return i - j;
        else 
           return -1;
    }

直接举例说明清晰一点。

这里写图片描述

在eclipse上运行一遍代码,测试结果。

public static void main(String[] args) {
        // TODO Auto-generated method stub
        String s = "abababca";
        String g = "abc";

        int[] next = new int[100];

        KMP_Alogrithm.getNext(s.toCharArray(), next);

        System.out.println(KMP_Alogrithm.KMP(s.toCharArray(), g.toCharArray(), next));
    }

这里写图片描述

输出结果正确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值