字符串匹配(下) - KMP算法

  • 核心思想:模式串在匹配主串的过程中,当遇到不匹配的字符时,多后滑几位(类似BM算法)
  • 思路
    • 优化好前缀的后缀子串和模式串的前缀子串的比较
    • 遇到坏字符时,根据好前缀,把模式串一次移动多位
    • 好前缀本身,查询可匹配的前后缀子串,取最长子串
    • 最长可匹配后缀子串 - 最长可匹配前缀子串
  • 求好前缀的最长可匹配前缀和后缀子串
    • 和主串无关
    • 预先处理模式串
    • 主串和模式串匹配过程中,直接拿来用
  • 空间复杂度:O(m)
  • 时间复杂度:O(m+n)
// a, b分别是主串和模式串
function kmp(a, b) {
	//n, m分别是主串和模式串的长度。
	n = a.length
	m = b.length
  	next = getNexts(b);
  	//指针i遍历主串,指针j遍历模式串
  	let j = 0;
  	for (let i = 0; i < n; ++i) {
  		//有好前缀时,如果存在坏字符
    	while (j > 0 && a[i] != b[j]) { 
    		//根据next,得出模式串的后移位数
      		j = next [j - 1] + 1;
    	}
    	//好前缀
	    if (a[i] == b[j]) {
	      ++j;
	    }
	    //好前缀和模式串相同,找到了
	    if (j == m) { 
	      return i - m + 1;
	    }
	}
  	return -1;
}
//失效函数,求next数组(根据i-1的值计算i值)
function getNexts(b){
	const m = b.length
	/**
	next数组
	下标:前缀结尾字符下标
	值:该前缀,最长可匹配前缀子串,的结尾字符下标
	*/
	const next = [-1]	
	//k为最长...,的结尾字符下标
	let k = -1
	for(let i=1;i<m;i++){
		//最长...存在时,指针后移比较(根据i-1推导i,递归该过程)
		while(k != -1 && b[k+1] != b[i]){
			//取次大可匹配前缀子串,再次比较
			k = next[k]
		}
		if(b[k+1] == b[i]){
			k++
		}
		next[i] = k
	}
	return next
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值