问题
Implement strStr().
Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.
代码
int hashCode(char* needle , int c)
{
int hashcode = 0;
for (int i = 0 ; i < c ; i++) {
hashcode <<= 1;
hashcode += needle[i];
}
return hashcode;
}
void putInMap(map<int , list<int>* >& map, int hashCode , int value)
{
list<int> *list_s = map[hashCode];
if (!list_s) {
list_s = new list<int>;
map[hashCode] = list_s;
}
list_s->push_back(value);
}
class Solution {
public:
char *strStr(char *haystack, char *needle)
{
if (*needle =='\0')
return haystack;
if (!haystack || !needle || *needle == '\0' || *haystack =='\0') {
return NULL;
}
map<int , list<int >* > map;
size_t size = strlen(haystack);
size_t needle_size = strlen(needle);
if(size < needle_size)
return NULL;
int tempHashCode = hashCode(haystack, needle_size);
int myHashCode = hashCode(needle, needle_size);
/* set int map */
putInMap(map , tempHashCode , 0);
int gap = 1 << (needle_size -1);
for (int i = needle_size; i < size ; i++) {
tempHashCode -= haystack[ i - needle_size] << (needle_size - 1);
tempHashCode <<= 1;
tempHashCode += haystack[i];
putInMap(map , tempHashCode , (i - needle_size + 1));
}
list<int> *tempList = map[myHashCode];
if (!tempList) {
return NULL;
}else{
while (tempList->size() != 0) {
int tempI = tempList->front();
tempList->pop_front();
char *a = haystack + tempI;
char *b = needle;
while (*b != '\0') {
if(*b ++ != *a ++)
break;
}
if (*b == '\0') {
return haystack + tempI;
}
}
}
return NULL;
}
};
分析
我还没有学会用kmp算法做算法查找,我选择的一个方法是使用hash先让所有的字符串散列。 然后用map查找,总的复杂度是nlogn,因为每次插入map中,需要logn的开销(map使用红黑树实现的),然后遍历的时候也用到了一个小技巧,hash值的算取。
总结
这个我觉得用kmp算法可能会更省代码和空间一些。