KMP算法

KMP算法主要解决字符串匹配问题,应用广泛。主要的思想就是尽量不让以前走的路白走,相对于暴力算法,如果匹配失败,不会直接退回到最前面的位置,而是让字符串后退,那是怎么实现的呢?首先引入了next数组,而next数组的求法其实和KMP算法的核心思想是一样的,首先看下什么是next数组。

next数组就是子串s[0...i]的最长相等前后缀的前缀最后一位的下标。前后缀不能是子串本身。

例如字符串ababaab

已知next[0]=-1,next[1]=-1,next[2]=0,next[3]=1,我们来求一下next[4]

 

在next[3]的基础上,箭头两个已经相等,是不是只要下一个相等,就是最长相等前后缀了,即s[next[3]+1]=s[4],当然这是最简单的情况,那我们继续来求next[5]

可恶箭头的下一个竟然不相等了!那肯定是前后缀缩短长度了。 缩到多短呢,那肯定是听取前人的经验,到next[j]了,当他一直退退退都不能匹配,那就是推到-1也不能匹配,那就是没有前后缀相等的情况了,然而当我们突然发现s[j+1]等与s[5]了,我们要找的人来了,next[5]=j+1。

代码如下:

void nextval(string needle,int m){
        int j=-1;
        next[0]=-1;
        for(int i=1;i<m;i++){
            while(j!=-1&&needle[i]!=needle[j+1]){
                j=next[j];
            }
            if(needle[i]==needle[j+1]) j++;
            next[i]=j;
        }
    }

那么求next数组是干嘛用的呢,就是当j+1位失配时,j应该退回的位置,很容易理解,因为next就是前后缀相等的最大坐标,前缀等于后缀,那就让前缀退回到相等的后缀那里去。代码如下:

int strStr(string haystack, string needle) {
        int m=needle.size();
        int n=haystack.size();
        nextval(needle,m);
        int j=-1;
        for(int i=0;i<n;i++){
		while(j!=-1&&needle[j+1]!=haystack[i]){
			j=next[j];
		}
		if(needle[j+1]==haystack[i]){
			j++;
		}
		if(j==m-1) return i-m+1;//返回第一个匹配的下标,从0开始
	}
	return -1;//没有匹配的情况
    }

其实还有有点云里雾里的,慢慢理解吧

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值