最近研究算法,才发现字符串匹配竟然有这么多的算法可以选择,并且对字符串查找的效率也有提升,在这里对几个典型的算法做一个总结。各种算法的原理在所有算法书籍或者Google都能找到,这里就不再重复,只将自己实现的java版代码贴下。

简单匹配

/**
     * 原始字符串匹配
     *
     * @param target
     * @param pattern
     * @return
     */
    public static int originMatch(String target, String pattern) {
        int flag = -1;
        int tlen = target.length();
        int plen = pattern.length();
        int i = 0, j = 0;

        while ((i + j) < tlen && j < plen) {
            if (target.charAt(i + j) == pattern.charAt(j)) {
                j++;
            } else {
                i++;
                j = 0;
            }
        }

        if (j == plen) {
            flag = i;
        }
        return flag;
    }

KMP算法匹配

    /**
     * 采用KMP算法匹配字符串
     *
     * @param target
     * @param pattern
     * @return
     */
    public static int kmpMatch(String target, String pattern) {
        int flag = -1;
        char[] ps = pattern.toCharArray();
        char[] ts = target.toCharArray();
        int[] next = getNext(ps);
        int i = 0;
        int j = 0;
        while (i < ts.length && j < ps.length) {

            if (j == -1 || ps[j] == ts[i]) {
                i++;
                j++;
            } else {
//                if (next[j] == -1) {
//                    i++;
//                    j = 0;
//                } else if (next[j] == 0) {
//                    j = 0;
//                } else if (next[j] > 0) {
//                    j = next[j];
//                }
                j = next[j];
            }

        }

        if (j == ps.length) {
            flag = i - j;
        }
        return flag;
    }

    /**
     * KMP 取模式值next[n]
     *
     * @param ps
     * @return
     */
    public static int[] getNext(char[] ps) {
        int[] next = new int[ps.length];
        next[0] = -1;
        // 标记字符在字符数组中的位置
        int i = 0;
        // 标记取值模式数组的位置
        int j = -1;
        while (i < ps.length - 1) {
            if (j == -1 || ps[i] == ps[j]) {
                i++;
                j++;
                if (ps[i] != ps[j]) {
                    next[i] = j;
                } else {
                    next[i] = next[j];
                }
            } else {
                j = next[j];
            }
        }
        return next;
    }

Sunday算法匹配

    /**
     * 字符串匹配之Sunday算法
     *
     * @return
     */
    public static int sundayMatch(String target, String pattern) {
        int flag = -1;
        int tlen = target.length();
        int plen = pattern.length();
        int i = 0;// 标记目标串的字符的开始位置
        int j = 0;// 标记模式串的字符位置
        int m = 0; //标记目标串匹配模式串的动态位置

        while (i < tlen && j < plen) {
            if (i == 0 && j == 0) {
                if (target.charAt(i) != pattern.charAt(j)) {
                    m = i + plen;
                    for (int k = plen - 1; k >= 0; k--) {
                        if (pattern.charAt(k) == target.charAt(m)) {
                            i = i + (plen - k);
                            break;
                        }
                    }
                }
            }
            if (target.charAt(i) != pattern.charAt(j)) {
                for (int k = (i + plen - j); k < tlen; k++) {
                    if (target.charAt(k) == pattern.charAt(plen - 1)) {
                        m = k;
                        i = m - plen + 1;
                        j = 0;
                        break;

                    }
                }
            } else {
                i++;
                j++;
            }
        }
        if (j == plen) {
            flag = i - plen;
        }
        return flag;
    }

代码的github地址:
github地址

留下的几个好的参考博客:

KMP字符串模式匹配详解

字符串匹配算法 – Sunday算法


枫华絮语
4 声望2 粉丝

滴水穿石