一、问题描述:
https://leetcode.com/problems/implement-strstr/
Implement strStr().
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
Subscribe to see which companies asked this question
二、实现:
暴力匹配
int strStr(string haystack, string needle) {
if (haystack.length() < needle.length()) {
return -1;
}
if (haystack.length() == needle.length()) {
if (haystack == needle) {
return 0;
}
return -1;
}
for (int i = 0; i < haystack.length()-needle.length()+1; ++i) {
string tmp = haystack.substr(i, needle.length());
cout << tmp << endl;
if (tmp == needle) {
return i;
}
}
return -1;
}
KMP
注意大坑!
j<(int)needle.length()
不加(int)的话,由于length()为无符号类型,当j==-1时将会被转化为INT_MAX!
public:
int strStr(string haystack, string needle) {
if (needle.empty()) return 0;
if (haystack.empty()) return -1;
if (haystack.length() == needle.length()) {
if (haystack == needle) return 0;
return -1;
}
vector<int> nextArray(needle.length(), 0);
generateNext(nextArray, needle);
int i = 0, j =0;
while(i<haystack.length() && j<(int)needle.length()) {
if (j==-1 || haystack[i]==needle[j]) {
i++;
j++;
}
else j = nextArray[j];
}
if (j == needle.length()) return i-j;
return -1;
}
private:
void generateNext(vector<int> &nextArray, string needle) {
nextArray[0] = -1;
int k = -1, j = 0;
while(j < needle.length()-1) {
if (k==-1 || needle[k]==needle[j]) {
k++;
j++;
if (needle[j] != needle[k]) nextArray[j] = k;
else nextArray[j] = nextArray[k];
}
else k = nextArray[k];
}
}
====================================================================================================================== 最近做一道题,用到上面这种KMP写法,但是却超时了。 理论上10^6的长度应该是不会超过1s的,翻了一下算法导论,将上述KMP算法更改如下:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
void generateNext(vector<int> &nextArray, string needle) {
nextArray[0] = -1;
int k=-1, q;
for (q = 1; q < needle.length(); ++q) {
while (k>=0 && needle[k+1]!=needle[q])
k = nextArray[k];
if (needle[k+1] == needle[q])
k++;
nextArray[q] = k;
}
// for (int i = 0; i < needle.length(); ++i) {
// cout << nextArray[i] << endl;
// }
}
int match(string hayStack, string needle, vector<int>& nextArray) {
if (hayStack.length() < needle.length()) return 0;
if (hayStack.length() == needle.length()) {
if (hayStack == needle) return 1;
return 0;
}
int q=-1, i=0;
int cnt=0;
for (i = 0; i < hayStack.length(); ++i) {
while (q>=0 && needle[q+1]!=hayStack[i])
q = nextArray[q];
if (needle[q+1] == hayStack[i])
q++;
if (q == needle.length()-1) {
cnt++;
q = nextArray[q];
}
}
return cnt;
}
int main(int argc, char const *argv[]) {
string hayStack, needle;
while (cin >> hayStack >> needle) {
vector<int> nextArray(needle.length(), 0);
generateNext(nextArray, needle);
int cnt = match(hayStack, needle, nextArray);
cout << cnt << endl;
}
return 0;
}
附:KMP讲解 http://blog.csdn.net/v_july_v/article/details/7041827