【算法第七天7.20】kmp算法

链接kmp算法-力扣28-找出字符串中第一个匹配项的下标

思路

1、next数组的获取:i:后缀的末位;j:前缀的末位
i 和 j 位置字符不同时,则说明当前的字符不能被统计到相等前后缀中,需要让j回退到他前一个位置next数组对应的值
i 和 j 位置字符相同时,则统一向后移动,说明后面还有可能有相等的字符
2、当 j 循环到最后时,一直相等(其实此时已经超出了模式串,到了模式串最后一位的后面),则可以返回第一匹配项的下标了

class Solution {
    public void getNext(int[] next, String s){
        int j = 0;
        next[0] = 0;
        // i是循环遍历原串s
        // j是循环模式串
        for (int i = 1; i<s.length(); i++){
            while(j > 0 && s.charAt(i) != s.charAt(j)){
                // 当遇到不相等的串时,需要回退到next数组当前位置对应的下标
                j=next[j-1];
            }
            // 如果i处的字符和j处的字符相等,则说明后面有可能还有相等的字符,则继续向前去找 最长前后缀
            if(s.charAt(i)==s.charAt(j)){
                j++;
            }
            // 更新当前位置的next数组
            next[i] = j;
        }
    }
    public int strStr(String haystack, String needle) {
    //模式串为空时,则直接返回0
        if(needle.length()==0){
            return 0;
        }
        int[] next = new int[needle.length()];
        // 获取needle字符串的next数组
        getNext(next,needle);
        // 遍历原串和子串
        int j = 0;
        for(int i = 0; i<haystack.length();i++){
            while(j > 0 && haystack.charAt(i) != needle.charAt(j)){
                // 当不相等时,回退到next数组对应前一位的坐标位置
                j = next[j-1];
            }
            //相等,则一直往后比较
            if(haystack.charAt(i)==needle.charAt(j)){
                j++;
            }
            // 当j循环到最后时(其实此时已经超出了模式串,到了模式串最后一位的后面),则可以返回
            if(j==needle.length()){
                return (i-needle.length()+1);
            }
        }

        return -1;
    }
}

你可能感兴趣的:(算法,数据结构)