您的位置:首页 > 其它

Leetcode28. kmp算法实现字符串匹配

2017-09-29 20:43 274 查看

Leetcode28. Implement strStr()

题目

Implement strStr().

Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

解题分析

提到字符串匹配,就不得不提及kmp算法。kmp算法巧妙地消除了指针i的回溯问题,只需确定下次匹配j的位置即可,使得问题的复杂度由O(m*n)下降到O(m+n)。在kmp算法中,为了确定在匹配不成功时下次匹配时j的位置,引入了next[]数组,next[j]的值表示needle[0…j-1]中最长后缀的长度等于相同字符序列的前缀。

kmp算法的思想就是:在匹配过程中,若发生不匹配的情况,如果next[j]>=0,则目标串的指针i不变,将模式串的指针j移动到next[j]的位置继续进行匹配;若next[j]=-1,则将i右移1位,并将j置0,继续进行比较。

kmp算法的关键在于求算next[]数组的值,即求算模式串每个位置处的最长后缀与前缀相同的长度。

根据定义next[0]=-1,假设next[j]=k, 即needle[0…k-1]==needle[j-k,j-1]。若needle[j]==needle[k],则有needle[0..k]==needle[j-k,j],很显然,next[j+1]=next[j]+1=k+1。若needle[j]!=needle[k],则可以把其看做模式匹配的问题,即匹配失败的时候,可知k=next[k]。

源代码

class Solution {
public:
int strStr(string haystack, string needle) {
int size1 = haystack.size(), size2 = needle.size(), i = 0, j = 0;
if (size2 == 0) {
return 0;
}
int* next = new int[size2];
getNext(needle, next);
while (i < size1) {
if (j == -1 || haystack[i] == needle[j]) {
i++;
j++;
}
else {
j = next[j];
}
if (j == size2) {
return i - size2;
}
}
return -1;
}

void getNext(string s, int* next) {
int j = 0, k = -1;
next[0] = -1;
while (j < s.size() - 1) {
if (k == -1 || s[j] == s[k]) {
j++;
k++;
next[j] = k;
}
else {
k = next[k];
}
}
}
};


以上是我对这道问题的一些想法,有问题还请在评论区讨论留言~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: