算法篇(1) KMP JS实现最优查找子串
阅读原文时间:2023年07月11日阅读:3
var strStr = function (haystack, needle) {
      let i=0,
        j = 0;
      let length = haystack.length;
      let next = getNext(needle, new Array(needle.length).fill(0));
      if (needle === "") {
        return 0;
      }
      while(i<haystack.length&&j<needle.length) {
        if (haystack[i] === needle[j]) {
          i++;
          j++;
          console.log(haystack[i],needle[j])
        } else {
          if (j > 0) {
            j = next[j - 1];
          }  else {
              i++;
          }
        }
        if (j === needle.length) {
          return i - j ;
        }
      }
      return -1;
    };
    console.log(strStr("mississippi", "issip"));
    function getNext(str, next) {
      let i,j = 0;
      let length = str.length;
      for (i = 1; i < length; i++) {
        while (j > 0 && str[i] != str[j]) {
          j = next[j - 1];
        }
        if (str[i] === str[j]) {
          j++;
          next[i] = j;
        }
      }
      return next;
    }


function getNext(str) {
    let i = 1;
    let j = 0;
    let nextArr = new Array(str.length).fill(0);
    nextArr[0] = str.length;
    while(i<str.length) {
        if(j==0 || str[i] === str[j]) {
            j++;
            i++;
            nextArr[i] = j;
        } else {
            j=nextArr[j];
        }
    }
    return nextArr;
}

/**
 *
 */
function search(str1,str2) {
    let i = 0;
    let j = 0;
    let next = getNext(str2);
    console.log(next)
    while(j<next[0]) {
        if(str1[i] === str2[j]) {
            i++;
            j++;
            if(j === next[0]) {
                return i-j
            }
        } else if(j>0) {
            j = next[j];
        } else {
            i++;
        }
    }
    return false;
}


issip的最大相同前后缀为 i
i is iss issi issip
0 0   0   1     0
mississippi
i//m!=i 前进一位
 issip//s!=p 根据前缀表向右移位
 00010
    issip//相同,返回第一个字符的索引 即i-j i为当前主串字符的索引,j为子串字符的索引