Implement strStr().
Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.
» Solve this problem
字符串匹配问题,KMP算法。
我采用的是不是最高效最原始的KMP,而是使用了一种容易理解一点的匹配算法。
这个算法中的next包含的信息没有KMP中的next包含的信息丰富。
假设匹配串pattern下标从0到length-1,length是匹配串长度。
next[i]的含义就是 pattern[0]..pattern[next[i]] 与 pattern[i - next[i]]..pattern[i]相同。
例如:
pattern = "isssip",则
next = [-1,-1,-1,0,-1]。
假设待匹配串为S,我们不难得出伪代码:
for (int i = 0, j = -1; i < S.length; i++) {
while (j >= 0 && pattern[j + 1] != S[i]) {
j = next[j];
}
if (pattern[j + 1] == S[i]) {
j++;
}
if (j == pattern.length - 1) {
匹配成功,开始位置为i - pattern.length + 1
}
}
求next数组,其实就是一个pattern与自己匹配的过程,所以伪代码和上面的几乎相同:
next[0] = -1;
for (int i = 1, j = -1; i < pattern.length; i++) {
while (j >= 0 && pattern[j + 1] != pattern[i]) {
j = next[j];
}
if (pattern[j + 1] == pattern[i]) {
j++;
}
next[i] = j;
}
P.S. 特殊情况:空或者""
class Solution {
public:
char *strStr(char *haystack, char *needle) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if (haystack == NULL || needle == NULL) {
return NULL;
}
int needleLen = 0;
while (needle[needleLen] != '\0') {
needleLen++;
}
if (needleLen == 0) {
return haystack;
}
int next[needleLen];
next[0] = -1;
for (int i = 1, j = -1; i < needleLen; i++) {
while (j >= 0 && needle[j + 1] != needle[i]) {
j = next[j];
}
if (needle[j + 1] == needle[i]) {
j++;
}
next[i] = j;
}
for (int i = 0, j = -1; haystack[i] != '\0'; i++) {
while (j >= 0 && needle[j + 1] != haystack[i]) {
j = next[j];
}
if (needle[j + 1] == haystack[i]) {
j++;
}
if (j == needleLen - 1) {
return haystack + i - needleLen + 1;
}
}
return NULL;
}
};