KMP算法心得
1 关于next数组
(1)写代码的时候为了避免逻辑混乱, 所以最好还是使得next数组从第零位开始记录, 这样的话, 当本位置发生比较冲突时, 可以直接取本位置存储的数值作为下一次进行比较的位置, 而不需要进行加一或者减一的操作
(2)next数组中记录的是本位置最长公共前后缀的长度,在这里我们需要理解什么是最长公共前后缀:
最长公共前后缀的条件:
** 不包含本位置
** 不能包含本位置之前的全部字符
2 比较的时候,如果第一位就发生了比较冲突, 下一次应该是将源字符串的下一个位置与目标字符串的本位置进行比较,
如果不是第一位比较发生冲突, 那么将会是将源字符串的本位置与目标字符串的新位置进行比较,
这一点之前没有搞清, 所以吃了一点亏
3 如果忘了具体的实施, 了解一下理论即可, 主要是在写代码的过程中上面两点出现了问题, 代码如下:
1 /** 2 * @param {string} s 3 * @return {array} 4 */ 5 const getNext = function (s) { 6 7 let stringArr = s.split("") 8 let nextArr = [] 9 for(let i = 0, length = stringArr.length; i < length; i++) { 10 11 let count = 1 12 while(judge(stringArr, count, i) && count<i) { 13 count++ 14 } 15 16 nextArr[i] = --count 17 } 18 19 return nextArr 20 } 21 22 /** 23 * 24 * @param {array} array 25 * @param {number} n 26 * @param {number} endIndex 27 * @return {boolean} 28 */ 29 const judge = function (array, n, endIndex) { 30 31 let left = 0 32 let right = endIndex-n 33 34 if(endIndex<=1) { 35 return false 36 } 37 38 while(left<n) { 39 if(array[left] !== array[right]) { 40 return false 41 } 42 left++ 43 right++ 44 } 45 return true 46 } 47 48 49 /** 50 * 51 * @param {string} sourceStr 52 * @param {string} targetStr 53 */ 54 const indexof = function (sourceStr, targetStr) { 55 56 let nextArr = getNext(targetStr) 57 58 for(let source = 0, target = 0, length = sourceStr.length; source < length; source++,target++) { 59 60 if(sourceStr.length-source < nextArr.length-target) { 61 return -1 62 }else if(target === nextArr.length-1 && sourceStr[source] === targetStr[target]){ 63 console.log("找到了"+(source-targetStr.length+1)) 64 return source-targetStr.length+1 65 } 66 if(sourceStr.charAt(source) !== targetStr.charAt(target)) { 67 if(target!==0) { 68 source-- 69 } 70 target = nextArr[target]-1 71 } 72 73 } 74 } 75 76 console.log(indexof("aabaac","aa"))
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通