102-算法应用【KMP算法】代码实现

KMP算法实现

介绍

KMP算法,字符串匹配算法,它与BM算法很相近。假设主串是m,模式串是p。在模式串与主串匹配的过程中,当遇到不可匹配的字符的时候,我们希望找到一些规律,可以将模式串往后多滑动几位,跳过那些肯定不会匹配的情况。

但是大多数情况下,如果主串不是很长,我们会倾向使用BF(朴素)算法,即“暴力匹配”算法,从第一个字符开始,每次滑动一个,完全匹配。

 

分析

要尽可能多的向右滑动,KMP的算法核心是计算next函数的值,即“好前缀”中所存在的最大公共元素长度,假设模式串的第j位字符与主串的第i位字符不匹配,那么模式串[0, j-1]即为“好前缀”,j位字符成为“坏字符”,通过“好前缀”计算出的最大公共元素长度为k,则,模式串可向右滑动j-k-1位,i不变,继续匹配。

 

 

实现

下面是用java实现一个KMP算法:

/**
 * KMP算法
 */
public class KMPTest {


    /**
     * KMP匹配算法
     * @param m 主串
     * @param s 字串
     * @return 匹配下标
     */
    public static int match(char[] m, char[] s){
        int i, j, k;
        i = 0; //主串下标
        j = 0; //模式串下标
        while (i < m.length) {
            if (m[i++] == s[j++]) {
                if (j == s.length)
                    return i - j;
                continue;
            }
            k = next(s, j - 1);
            j = j - k - 1;
        }

        return -1;
    }

    /**
     * 计算next函数的值——求"好前缀"的最大公共字串长度
     * @param s 模式串
     * @param j 好前缀下标[0, j-1]
     * @return
     */
    public static int next(char[] s, int j) {
        int m, n;
        boolean isEquals;
        for (m = j-1, n = 1; m > 0 && n < j; m--, n++) {
            isEquals = true;
            int a = 0, b = n;
            while (a < m && b < j) {
                if (s[a++] != s[b++]) {
                    isEquals = false;
                    break;
                }
            }
            if (isEquals)
                return m;
        }
        return 0;
    }

}

 

posted @ 2021-03-19 16:27  温柔的星空,让你感动  阅读(49)  评论(0编辑  收藏  举报