KMP算法JS实现
参考阮一峰的《字符串匹配的KMP算法》,用JS实现一版,备忘~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | // 主串 let mainString = "BBC ABCDAB ABCDABCDABDEDC" ; // 模式串 let patternString = "ABCDABD" ; /** * 算出《部分匹配表》Partial Match Table * 参考文档:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html * @method * @param {String} patternString 要计算部分匹配表的模式字符串 * @return {Array} 计算出的部分匹配表 */ let getPartialMatchTable = (patternString = "" ) => { if (patternString.length === 0) return []; // 模式串为1个字符时,前缀后缀不存在公有元素,因此长度0 let pmt = [0]; // 至少2个字符才有计算前缀和后缀的必要 let startingLength = 2; while (startingLength <= patternString.length) { let temp = patternString.substring(0, startingLength); let length = temp.length; // 算出所有前缀 let prefix = temp // 前缀是不包含最后一个字符的 .substring(0, length - 1) .split( "" ) .map((_, index) => { return temp.substring(0, index + 1); }); // 算出所有后缀 let suffix = temp // 后缀是不包含第一个字符的 .substring(1) .split( "" ) .map((_, index) => { return temp.substring(index + 1); }); // 前缀和后缀的最长共有元素长度 let publicLength = 0; // 比较前缀后缀得出最长公共字符长度 prefix.forEach((preitem) => { suffix.forEach((sufitem) => { if (preitem === sufitem) { publicLength = preitem.length > publicLength ? preitem.length : publicLength; } }); }); pmt.push(publicLength); startingLength++; } return pmt; }; let pmt = getPartialMatchTable(patternString); // 两个索引,从位置0开始匹配 let mainIndex = 0; let patternIndex = 0; while (mainIndex < mainString.length && patternIndex < patternString.length) { // 匹配上了,继续比较下一个字符 if (mainString[mainIndex] === patternString[patternIndex]) { patternIndex++; mainIndex++; } else if (patternIndex > 0) { // 没匹配上,并且前面已匹配字符数 > 0,模式串索引往后移动 patternIndex - pmt[patternIndex - 1] 位 patternIndex -= patternIndex - pmt[patternIndex - 1]; } else { // 一个字符都没匹配上 mainIndex++; } } if (patternIndex === patternString.length) { console.log( `mainString包含patternString,索引位置为${mainIndex - patternString.length}至${ mainIndex - 1 }` ); } else { console.log( "mainString不包含patternString" ); } |
2019-09-17 23:21:38
复制成功
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步