ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

KMP 算法的 JS 实现

2021-09-12 19:31:30  阅读:237  来源: 互联网

标签:字符 匹配 ++ s2 next 算法 let KMP JS


KMP (Knuth-Morris-Pratt) 字符串查找算法可在一个字符串 S 内查找一个词 P 的出现位置。 一个词在不匹配时本身就包含足够的信息来确定下一个匹配可能的开始位置,此算法利用这一特性以避免重新检查先前匹配的字符。

  • 朴素字符串匹配算法(暴力)- s 串中查找子串 p

    • 挨个字符遍历 s 中的字符,与 p[0] 相等时

      • 循环遍历 p, 两者索引同时后移
      • 最终 p 的索引是否等于 p 的长度
      let i = x, j = 1;//i -> s[x], j => p
      while (i < s.length && j < p.length && s[i] === p[j]) {
          ++i;
          ++j;
      }
      if (j === p.length) reutrn x;// 在当前位置匹配
      
  • KMP 算法

  • 定义了一个公共前缀的概念:当前字符之前的字符串中,相同前缀后缀长度为多少。

    • 首先建立一个与模式串 p 等长的存储 p 各个位置公共前缀长度的数组 next
      • next[0] = 0
    • 计算 next
        let next = new Array(m);//next数组
        next[0] = 0;
        for (let i = 1, j = 0; i < m; i++){
            while (j && s[i] !== p[j]) {//不匹配,左移
                j = next[j - 1];
            }
            if (s[i] === p[j]) ++j;//匹配, j 右移 + 1
            next[i] = j;
        }
    
  • 通过 next 数组,在某个字符失配的时候,该字符对应的 next 值会告诉你下一步匹配中,模式串应该跳到哪个位置( next [j] )。如果 next [j] 等于 0,则跳到模式串的开头字符,若 next [j] > 0,代表下次匹配跳到 j 之前的某个字符,而不是跳到开头,且具体跳过了 next [j] 个字符。实现了 O(n + m) 的时间复杂度。

  • JS 实现

const kmp = (s1, s2) => {
    const n = s1.length;//模式串
    const m = s2.length;//匹配串
    
    if (!m) return 0;//匹配串为空
    let next = new Array(m);//next数组
    next[0] = 0;
    for (let i = 1, j = 0; i < m; i++){
        while (j && s2[i] !== s2[j]) {//不匹配,左移
            j = next[j - 1];
        }
        if (s2[i] === s2[j]) ++j;//匹配 i j右移
        next[i] = j;
    }
	//匹配
    for (let i = 0, j = 0; i < n; i++){
        while (j && s1[i] !== s2[j]) {// 失配 左移
            j = next[j - 1];
        }
        if (s1[i] === s2[j]) ++j;// 匹配 j + 1
        if (j === m) return i - m + 1;
    }
    return - 1;
}

标签:字符,匹配,++,s2,next,算法,let,KMP,JS
来源: https://www.cnblogs.com/honey-cat/p/15259629.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有