(KMP) alogrithm 实现

#include<iostream>
#include<string>
#include<vector>
using namespace std;


void get_next(const char * subStr,vector<int>&next )
{
  next[0] = strlen(subStr);
  next[1]= 0;
  next[2]=1;
  int i = 3;
  int j =2;
  while(j < strlen(subStr))
  {
    if(subStr[i-1]== subStr[next[i-1]] )
	{
	  next[i]=next[i-1]+1;
	}
	else
	{
	  next[i]=next[i-1];
	}
	i++;
	j++;
  }
}

int index_KMP(string s,string t)
{
   int i =0;
   int j =0;
   vector<string>sTemp(s.length()+1);
   vector<string>tTemp(t.length()+1);

   while( i < s.length())
   {
      sTemp[i+1]=s[i];
	  i++;
   }
   sTemp[0]= s.length();
   while(j <t.length())
   {
      tTemp[j+1]=t[j];
	  j++;
   }
   tTemp[0]=t.length();
   i=1;
   j=1;
   vector<int>next(t.length()+1);
   get_next(t.c_str(),next);

   int slen = s.length();
   int tLen= t.length();
   while(i <= slen && j<= tLen)
   {
	   if(sTemp[i] == tTemp[j])
	   {
	      i++;
		  j++;
	   }
	   else if(sTemp[i] != tTemp[j] && 0 != j)
	   {
	      j=next[j];
	   }
	   else if(0 == j)
	   {
	     i++;
		 j++;
	   }
   }
   
   if(j >tLen)
   {
	   return i-tLen;  
   }
   
   return 0;
}

int main(int _args,char *arg[])
{
	
	string s ="abcdabcbcabcabc";
	string t="abcabc";
	cout<<"s ="<<s<<endl;
	cout<<"t ="<<t<<endl;
	int nResult = index_KMP(s,t);
	if(0 == nResult)
		cout<<"匹配失败"<<endl;
	else
		cout<<"在第"<<nResult<<"找到匹配项"<<endl;
	
	return 0;
}
// 上面的代码是位序为1的kmp
KMP算法中的next函数解析:


位序    1  2 3 4 5  6
模式串  a  b c a b  c
next值  0  1 1 1 2  3


第一位的next值为0,第二位的next值为1


以上是位序从1开始:
第三位的求解:
看前一位为2,模式串为b与对应的next值为1,将第二位的模式串与第一位的模式串比较,不等则为1,
若相等则在第二位的next值上加1




位序从0开始:
位序    0  1 2 3 4  5
模式串  a  b c a b  c
next值  -1 0 0 0 1  2


默认第一位和第二位为:-1,0


第三位:
看第二位,第二位的模式串为b与对应的next值为0,将第二位的模式串与第一位的模式串比较,不等则为0
第四位:
看第三位,第三位的模式串为c与对应的next值为0,将第三位的模式串与第一位的模式串比较,不等则为0
第六位:
看第5位,第四位的模式串为a,next值为0,发现a与第一位模式串比较相等则next=0+1;将第五位的模式串next值加1
以上next值分两种情况求解
再就是index_KMP()函数的解析:
匹配过程:
        1 2 3 4 5 6  7 8  9 10 11 12 13 14 15
源串为:"a  b  c  d  a  b  c   b   c   a   b     c   a   b     c " 变量指针为i
            j         1  2  3  4   5     6
匹配串为:" a b c a  b   c "  变量指针为j
  next[j]  0 1 1 1  2   3
初始化 i=1,j=1
1.当i=4 , j=4时,匹配不相等,j=next[j] 通过函数get_next可求得next值,j=1,i值不发生变化
2.i=4,j=1,时,源串为d,模式串为a 不匹配,则j=next[j]=0,当j=0时,i++,j++
3.i=5,j=1时,源串a 与模式串a相等,i++,j++同理 比较到i=8,j=4时,源字符为b,模式串为a不相等,j=next[4]=1,i值不变
4.i=8,j=1时,源串b != 模式串a  ,j=next[j]=0 ,i++,j++
5.i=9 ,j=1,     c !=       a,j=next[j]=0,i++,j++
6.i=10,j=1,     a=a,i++,j++,一直到i=15,j=6 仍然相等,i++,j++, i=16> 源串大小长度=15,j=7>模式串大小长度=6退出循环
函数返回值为 i-模式串长度=6 = 16-6=10; 结束
  
//现在恶补数据结构,看了2天才写出来,只知道怎么实现,但是具体原理还没弄透,先写到这,方便以后学习  




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值