KMP字符串匹配-JS

在这里插入图片描述
当串p与串t匹配的时候,返回的首次匹配的位置是i-j
如果遍历完,不匹配(i=n,j<m):i-j>n-m
在这里插入图片描述
任意j,考察集合

N(p,j)={0<=t<j | p[0,t) == p[j-t,j) }

即,p[j]的前缀p[0,j)中,所有匹配的真前缀和真后缀长度为next(j)
长度为t的前缀p[0,t)与长度为t的后缀p[j-t,j)必然相等
如果i、j分别指向的元素不匹配,p[i]≠p[j]N(p,j)中取第t个元素,令p[t]对准p[i]
这样使得前面的p[0,t)个元素就匹配了
解释:

  1. t=N[t](失配,一直递归,找next[next[next…]])
  2. N[++j]=++t;(匹配的时候,next[j+1]==next[j]+1)
    其中next[j]p[0,j)中最大匹配的真前缀和真后缀长度
next[j+1]≤next[j]+1

解释:下一项的最大匹配项不可能超过上一项+1
当下一项j项匹配,next[j+1]=next[j]+1;
如果不匹配,next[j+1]<next[j]+1一直递归,直到1+next[0]==0(next[0]= -1哨兵作用)

function buildNext(p){
	var m=p.length,j=0;
	var N=new Array(m);
	N[0]=-1;
	var t=N[0];
	//当字符串遍历完毕
	//当内部遍历到
	while(j<m-1){
	//匹配
		if(0>j||p[j]==p[t]){
			N[++j]=++t;
		}else{//失配
			t=N[t];
		}
	}
	//返回构造的next()表
	return N;
}

KMP找到第一个匹配的位置

//p模板字符串 t是主串
function match(p,t){
	var n=t.length,i=0;
	var m=p.length.j=0;
	var next=buildNext(p);
	while(j<m&&i<n){
		if(0>j||p[j]==t[i]){//当匹配的时候,携手共进
			++i;
			++j;
		}else{
			//适配的时候找next表
			j=next[j];
		}
	}
	//遍历完主串,但是p串还未遍历完,匹配失败 返回-1
	if(i-j>n-m) return -1;
	return i-j;
	
}

变体:

p[0,j)前的一致,当比较到j和t位置的,此时出现差异,j的内容与p[0,j)内容也一样,为了不重复比较,重复递归
buildNext()

N[++j]=++t;

变为

++t;
++j;
N[j]=p[j]!=p[t]?t:N[t];  
++t;
++j;
//存在匹配的前缀 保持前缀的next不变 
//不匹配改变next
N[j]=p[j]!=p[t]?t:N[t];  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值