1

原理:http://www.ruanyifeng.com/blo...
代码


import java.util.Arrays;

public class KMP {
    private static int[] prefixTable;

    /**
     * 部分匹配表
     * @param t
     * @return
     */
    public int[] getPrefixTable(char[] t){
        int n = t.length;
        int len;//匹配位置
        prefixTable = new int[n];
        prefixTable[0] = 0;

        for(int i = 1;i < n;i++){
            len  = prefixTable[i - 1];
            while(true){
                if(t[len] == t[i]){
                    len++;
                    prefixTable[i] = len;
                    break;
                }else{
                    if(len > 0)//下一个比较位置
                        len = prefixTable[len - 1];
                    else{
                        prefixTable[i] = 0;//
                        break;
                    }
                }
            }
        }
        return prefixTable;
    }

    public int[] match(char[] s,char[] t){
        int[] result = new int[s.length];//记录所有匹配的子串
        int count = 0;
        int j = 0;//记录子串匹配位置
        for(int i = 0;i < s.length;i++){
            if(s[i] == t[j]){//相等
                if(j == t.length - 1){//子串匹配完毕,记录位置,并且j=0找下一个匹配的子串
                    result[count++] = i - t.length + 1;
                    j = 0;
                }else{//子串匹配位置加1
                    j++;
                }
            }else{
                if(j > 0){//如果子串位置>0
                    j = prefixTable[j - 1];//不匹配的话从匹配表里面找到子串新的匹配位置
                    i--;//接着比较
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {
        KMP kmp= new KMP();
        char[] s = "ABCDAB ABCDABCDABDEABCDABD".toCharArray();
        char[] t = "ABCDABD".toCharArray();
        kmp.getPrefixTable(t);
        int index[] = kmp.match(s, t);
        System.out.println(Arrays.toString(index));
    }
}

输出结果

[11, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

yin
75 声望0 粉丝

毕业3年菜鸡,立志努力学习进入大厂