KMP算法--笔记

参考视频:bilibili
参考博客:KMP

void Getnext(int next[],String t)
{
	//k表前缀,j表后缀。
	//随着一次次的匹配成功,后缀的长度越来越长,1->length
	//前缀也是随着一次次匹配成功长度慢慢加长1,2,3..
	//前缀总是短的,类似一些小片段,一旦匹配不成功,咔嚓,当前的前缀片段就得换成别的片段重新匹配
	//换成哪个前缀片段?next[]里面的值指定了指针跳转的位置,因为每次匹配成功,next[]都记录了片段的长度,也即尾部指针。
   int j=0,k=-1;
   
   next[0]=-1;
   while(j<t.length-1)	//j=0,1,2,3...
   {
      if(k == -1 ||  t[j] == t[k])		//前缀字串=后缀字串
      {
		  //当 t[j] == t[k] 时,必然有"t[0]…t[k-1]" == " t[j-k]…t[j-1]"
		  //k代表前缀字串与后缀字串中有k个首字符连续匹配
		  //此时的 k 即是相同子串的长度。
         j++;k++;		//前缀字串指针右移,后缀字串指针右移
		 if (t[j] == t[k]) { // 当两个字符相等时要跳过,j++指向当前后缀字符+1,k++指向前缀字串+1

              next[j] = next[k];		//上级回溯指针赋给本级回溯指针

           } else {
			   next[j] = k;	//next[]存放子串长度
		   }
      }
      else k = next[k];	//回溯,当模式匹配串失配时,next数组对应的元素指导应该用T串的哪个元素作为前缀进行下一轮的匹配
   }
}
int KMP(String s,String t)
{
	//s表示目标串,t表示模式串
   int next[MaxSize],si=0;ti=0;
   Getnext(t,next);
   while(si<s.length&&ti<t.length)
   {
      if(ti==-1 || s[si]==t[ti])	//
      {
         si++;
         ti++;
      }
      else ti=next[ti];               //失配,回溯模式串指针,避免了模式串开头几个字符的重复匹配
	  //利用已经部分匹配这个有效信息,保持i指针不回溯,通过修改j指针,让模式串尽量地移动到有效的位置
   }
   if(ti>=t.length)
       return (si-t.length);         //匹配成功,返回子串的位置
   else
      return (-1);                  //没找到
}
发布了15 篇原创文章 · 获赞 0 · 访问量 393

猜你喜欢

转载自blog.csdn.net/mynameisJW/article/details/104315839
今日推荐