您的位置:首页 > 其它

笔试题41. LeetCode OJ (28)

2016-04-27 16:59 369 查看


这道题是字符串匹配题,返回匹配的位置。相信很多人都见过,我们很容易用暴力求解的方法解答出来,但是我想要借此说明的是一个算法----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数组的方法,希望对大家有用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: