LeetCode 28

这道题是字符串匹配题,返回匹配的位置。相信很多人都见过,我们很容易用暴力求解的方法解答出来,但是我想要借此说明的是一个算法----MKP算法,当然我在这里并不会详细介绍MKP算法,因为这个算法已经被很多人讲解过了,没有必要再讲一遍。我在这里想要做的是教大家如何构造出next数组,以及讲解匹配的规则。

      大家请看上面的图,假如我们的模式串为“abcdabcddd”,那么我们可以知道前缀和后缀匹配的情况了,图中的第一个数组就是前缀和后缀匹配的个数,由此我们怎么构造出next数组呢?我这里说一个很简单易懂的方法,将第一个数组的值向后平移移动一位,然后将第一位置为-1,next数组就搞定了^_^(next数组的作用我相信大家应该知道吧),那么我们就可以开始使用KMP算法来解题了,代码如下:

class Solution {
public:
    int strStr(string haystack, string needle) 
    {
        /*
            needle在haystack中第一次出现的位置-------->KMP算法
        */
        int hlen = haystack.size();
        int nlen = needle.size();
        if(hlen == 0 && nlen == 0)
        {
            return 0;
        }
        if(nlen == 0 )
        {
            return 0;
        }
        if(hlen == 0)
        {
            return -1;
        }
        //初始化next数组
        int *next = new int[nlen];
        for(int i=0; i<nlen; ++i)
        {
            next[i] = 0;
        }
        
        //构造next数组
        CreteNext(needle,next,nlen);
        
        //开始匹配
        int s=0;
        int p=0;
        while(s < hlen)
        {
            if(haystack[s] == needle[p])
            {
                ++s;
                ++p;
                if(p == nlen)
                {//匹配
                    return s-nlen;
                }
            }
            else if(next[p] == -1)
            {
                ++s;
            }
            else
            {
                p = next[p];
            }
        }
        //循环出来了说明没找到
        delete []next;
        return -1;
    }
    
    void CreteNext(string &need,int*& next, int n)
    {
        int left = 0;
        int right = 1;
        while(right < n)
        {
            if(need[right] == need[left])
            {
                next[right] = next[right-1]+1;
                ++left;
                //++right;
            }
            else if(need[right] == need[0])
            {
                next[right] = 1;
                left = 1;
                //++right;
            }
            else
            {
                left = 0;
                next[right] = 0;
                //++right;
            }
            ++right;
        }
        
        //next数组的数向右平移一位,然后next[0] = -1,netx数组就构造好了
        for(int j=n-1;j>0;--j)
        {
            next[j] = next[j-1];
        }
        next[0] = -1;
    }
};
相应的结果如下:



     大家如果不懂KMP算法的最好去了解一下,而懂KMP算法的人容易在构造next数组的时候犯错,所以我给大家说了一个很容易求解next数组的方法,希望对大家有用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值