Implement strStr().
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
两种方法:
1)bkdHash
2)kmp
代码分别如下:
//bkdHash
int strStr(string haystack, string needle) {
typedef unsigned long long ull;
int size1 = haystack.size(), size2 = needle.size();
if(size1<size2) return -1;
ull* Hash = new ull[size1+1];
ull nbase = 1; //因为size2是知道的,不用计算nbase[i]
int i, base = 31;
//并给haystack建立bkdHash
Hash[0] = 0;
for(i = 1; i <= size1; ++i)
Hash[i] = Hash[i-1]*base + haystack[i-1] - 'a' + 1;
//计算needle的hash值, 计算nbase,
ull h = 0;
for(i = 0; i < size2; ++i){
nbase = nbase*base;
h = h*base + needle[i] - 'a' + 1;
}
for(i = size2; i <= size1; ++i)
if(Hash[i] - Hash[i-size2]*nbase==h) return i-size2;
delete [] Hash;
return -1;
}
//kmp
int strStr(string haystack, string needle) {
int size1 = haystack.size(), size2 = needle.size();
if(size1<size2) return -1;
if(needle=="") return 0;
int *next = getNext(needle);
int i, j = 0;
for(i = 0; i < size1; ++i){
if(j==-1||haystack[i]==needle[j]){
if(++j==size2) return i-j+1;
}
else{
j = next[j];
i--;
}
}
delete [] next;
return -1;
}
//next数组
int* getNext(string& needle){
int i, j, size = needle.size();
int *next = new int[size];
memset(next, 0, sizeof(int)*size);
next[0] = -1;
for(i = 1; i < size; ++i){
j = i-1;
while(next[j]>=0){
if(needle[i-1]==needle[next[j]]){
next[i] = next[j] + 1;
break;
}
else j = next[j];
}
}
return next;
}