java - 算法 - kmp查找字符串第一次出现的位置

代码很简单,主要是思路可能会有点绕- -|||

reference:

https://www.bilibili.com/video/av54029771?p=162

 

package search;

public class MatchString {
    public static void main(String[] args){
        String str1 = "abc babd abcdabcd abcdabdcde";
        String str2 = "abcdabd"; //寻找str2 在str1中第一次出现的位置

        System.out.println(kmp(str1, str2));
        System.out.println(str1.charAt(kmp(str1,str2)));

    }

    public static int kmp(String str1, String str2){

        int[] mt = matchTable(str2);
        char[] cArr1 = str1.toCharArray();
        char[] cArr2 = str2.toCharArray();

        for(int i = 0, j = 0; i < str1.length(); i++ ){
            if(cArr1[i] == cArr2[j]){
                j++;
            }
            else{
                j = mt[j];
            }

            if(j == str2.length()){  //因为最后一个匹配成功后,j++了,所以这里是j = length()
                return i - str2.length() + 1;  //i此时指向了匹配成功的字符串的最后一个字符,所以要向前移动字符串长度 - 1 距离指向第一个字符,然后返回
            }
        }

        return -1;
    }


    public static int[] matchTable(String str){ //建立匹配表
        char[] cArr = str.toCharArray();
        int[] mt = new int[str.length()];
        mt[0] = 0;
        for(int i = 1, j = 0; i < cArr.length; i++){
            mt[i] = 0;
            if(cArr[i] == cArr[j]){
                j++;
            }
            else{
                j = 0;
            }
            mt[i] = j;
        }

        for(int i = 0; i < mt.length; i++){
            System.out.print(mt[i] + " ");
        }
        System.out.println();
        return mt;
    }
}

 

posted @ 2019-11-18 13:22  不咬人的兔子  阅读(1227)  评论(0编辑  收藏  举报