基于kmp算法实现字符串时间复杂度为O(N)级别的比较

一、暴力比较字符串时间复杂度为0(N*M)

    /**
         * 暴力匹配  时间复杂度为  O(N*M)
     * @param str1
     * @param str2
     * @return
     */
    public static boolean compareString(String str1, String str2) {
        int n = str1.length();
        int m = str2.length();
        char[] str1Arr = str1.toCharArray();
        char[] str2Arr = str2.toCharArray();
        if(n < m) {
            return false;
        }
        //i是str1的指针  j是str2的指针
        for(int i = 0; i < n; i++) {
            if(i + m > n) {
                return false;
            }
            int count = 0;
            for (int j = 0; j < m ; j++) {
                int k = i+j;
                if(str1Arr[k] == str2Arr[j]) {
                    count++;
                    continue;
                } else {
                    count = 0;
                    break;
                }
            }
            if(count == m) {
                return true;
            }
        }
        return false;
    }

二、基于KMP算法时间时间复杂度O(N+M)

    /**
     * 获取比较字符串的 next数组  next数据表示字符串每个字符的前缀字符串与后缀字符串相等时的最大值
     * @param str
     * @return
     */
    public static int[] next(String str) {
        if(str.length() == 1) {
            return new int[]{-1};
        }
        char[] strArr = str.toCharArray();
        //声明next数组 长度为源字符串的长度
        int[] next = new int[str.length()];
        next[0] = -1;
        next[1] = 0;
        //i为next数据的索引
        int i = 2;
        //cn为上一个相等前缀字符串的长度
        int cn = 0;
        while (i < next.length) {
            if(strArr[i-1] == strArr[cn]) {
                next[i++] = ++cn;
            } else if(cn > 0) {
                cn = next[cn];
            }   else {
                next[i++] = 0;
            }
        }
        return next;
    }

    /**
     * 基于kmp算法 比较两个字符串 返回比较字符串
     * @param str1
     * @param str2
     * @return
     */
    public static int compareStringByKMP(String str1, String str2) {

        int str1Length = str1.length();
        int str2Length = str2.length();


        char[] str1Arr = str1.toCharArray();
        char[] str2Arr = str2.toCharArray();

        int[] next = next(str2);

        int str1Index = 0;
        int str2Index = 0;

        while(str1Index < str1Length && str2Index < str2Length) {
            if(str1Arr[str1Index] == str2Arr[str2Index]) {
                str1Index++;
                str2Index++;
            } else {
                if(next[str2Index] == -1) {
                    str1Index++;
                } else {
                    str2Index = next[str2Index];
                }


            }
        }

        return str2Index == str2Length ? str1Index - str2Index : -1;
    }

三、扩展-基于KMP实现二叉树判断子树

我们给两个二叉树,然后将每个二叉树序列化,可以前中后随意。将序列化后的字符串进行按照kmp算法进行比较。

    原文作者:KMP算法
    原文地址: https://blog.csdn.net/lpp_dd/article/details/82683182
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞