Manacher算法、KMP算法

一、Manancher算法

Manacher算法用于查找子串中的回文,算法维持的三个变量十分重要pArr(下标所在位置字符回文长度)、index(回文中心)、pR(回文半径),这种算法比其他算法效率高的原因在于,它可以利用前面已计算过的回文来判断是否需要计算回文。算法在字符串每个字符之间已经开始和末尾都插入特殊字符(可以是任意字符包括所查字符串中字符),在计算回文时就避免了奇回文和偶回文的问题。

算法代码:

    public char[] manacherString(String str) {
        char[] charArr = str.toCharArray();
        char[] res = new char[str.length() * 2 + 1];
        int index = 0;
        for (int i = 0; i != res.length; i++) {
            res[i] = (i & 1) == 0 ? '#' : charArr[index++];
        }
        return res;
    }

    public int maxLcpsLength(String str) {
        if (str == null || str.length() == 0) {
            return 0;
        }
        char[] charArr = manacherString(str);
        int[] pArr = new int[charArr.length]; //下标所在位置字符回文长度
        int index = -1; //回文中心
        int pR = -1; //回文半径
        int max = Integer.MIN_VALUE;
        for (int i = 0; i != charArr.length; i++) {
            pArr[i] = pR > i ? Math.min(pArr[2 * index - i], pR - i) : 1;
            while (i + pArr[i] < charArr.length && i - pArr[i] > -1) {
                if (charArr[i + pArr[i]] == charArr[i - pArr[i]])
                    pArr[i]++;
                else {
                    break;
                }
            }
            if (i + pArr[i] > pR) {
                pR = i + pArr[i];
                index = i;
            }
            max = Math.max(max, pArr[i]);
        }
        return max - 1;
    }

二、KMP算法

KMP算法解决的是字符串匹配问题,也是利用一个next数组,利用前面的计算结果,为后面计算增加效率,next数字在KMP算法中至关重要。
next数组的定义:长度等于match字符串长度
值为下标所在字符前面字符串的标量(最长前缀和最长后缀相等情况下的长度)

算法代码

    public int getIndexOf(String s, String m) {
        if (s == null || m == null || m.length() < 1 || s.length() < m.length()) {
            return -1;
        }
        char[] ss = s.toCharArray();
        char[] ms = m.toCharArray();
        int si = 0;
        int mi = 0;
        int[] next = getNextArray(ms); //生成next数组
        while (si < ss.length && mi < ms.length) {
            if (ss[si] == ms[mi]) {
                si++;
                mi++;
            } else if (next[mi] == -1) {
                si++;
            } else {
                mi = next[mi];
            }
        }
        return mi == ms.length ? si - mi : -1;
    }


    public int[] getNextArray(char[] ms) {
        if (ms.length == 1) {
            return new int[] { -1 };
        }
        int[] next = new int[ms.length];
        next[0] = -1;
        next[1] = 0;
        int pos = 2;
        int cn = 0;
        while (pos < next.length) {
            if (ms[pos - 1] == ms[cn]) {
                next[pos++] = ++cn;
            } else if (cn > 0) {
                cn = next[cn];
            } else {
                next[pos++] = 0;
            }
        }
        return next;
    }

你可能感兴趣的:(KMP,Manacher)