kmp算法学习

来源:互联网 发布:外星文明不存在 知乎 编辑:程序博客网 时间:2024/06/06 00:15

kmp算法是实现快速匹配的一种算法,下面我们简单介绍一下它的原理,比如assadcabcmcgddss,我们要找到cabcbcg按照传统我们是一个一个匹配,比如在上述匹配中必有

assadcabcmcgddss中的cabc与cabcbcg中的cabc匹配成功,由于m和b不相等所以我们要结束匹配,传统的做法是让cabcbcg中的第一个字母c与assadcabcmcgddss中的字母中的第三个a比较,kmp算法则是直接让cabcbcg中的第二个字母a与m比较,为什么可以这么做呢,因为在第一次比较可以确定m前面的字母是cabc,(可以知道m前面必定有c字母)我们可以利用这部分信息指导我们下一次比较,这就是kmp的核心,对于一大串字符,我们要从中找到一个形如dabbdd的字符串,我们就可以构造一个next数组,这个数组的意义 : next[5]=1表示第六个字符d假如与某长串字符中的x字符(随便假定的)匹配失败,我们直接让第二个字符a与x字符匹配。如果第一个字符匹配就失败,我们则让第一个字符与某长串字符中的下一个字符匹配,为了方便next[0]=-1;我们只要理解了这一点,哪一点呢,比如要匹配ddsaasddd(后面简称T),当我们再于源字符串M(里面有很多字符)匹配最后一个d的时候与M中某个字符x匹配居然失败了,我们不要傻逼的再重头来一遍(这里指的是比如M中第10个位置起是ddsaasddx,按照上述的匹配失败,我们用T中的第一个字符d与M中第11个位置的字符d又开始比较起来)。因为我们已经知道了x前面的字符,可以利用这部分信息直接从T中找到正确位置与x匹配,而这个位置保存在next数组中,至于next数组生成代码自己看,慢慢看应该可以理解,很难说得清,逻辑比较多,理解原理,自己也可以写,


// KMP算法.cpp : 定义控制台应用程序的入口点。

//


#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;




//得到匹配next数组
void GetNext(string t,int *next)
{   int j=-1;
int i=0;
next[0]=-1;
while(i<t.length())
{
if(j==-1||t[i]==t[j]){
 ++i;
 ++j;
 next[i]=j;
if(i<t.length()&&t[i]==t[j]){//去除相等的情况
 int b=j;
        while(b>=0&&t[i]==t[b]) 
{
b=next[j];
   next[i]=b;
}
 }
}
else
j=next[j];//

}


}
int Index(string s,string t,int*next){
   int i=0,j=0;
 
  int strSize=s.length();
  int tSize=t.length();
   while((i<strSize)&&(j<tSize)){
  if((j==-1)||(s[i]==t[j])){
  i++;j++;
  }
  else{
  j=next[j];


  }
   
   }


   if(j==t.length()){
  return i-t.length();
     
   }
   else
  return -1;
  








}
int _tmain(int argc, _TCHAR* argv[])
{

string mm="abacac";
string str="fsgdgfdhfhfabacacgffhffgbd";
int*y=new int[mm.length()+1];
GetNext(mm,y);
cout<<Index(str,mm,y)<<endl;


return 0;
}

0 0
原创粉丝点击