LeetCode ImplementStrstr

class Solution {
public:
    char *strStr(char *haystack, char *needle) {
        if (haystack == NULL || needle == NULL) return NULL;
        int wpos[256];
        char cur = 0;
        int len = 0;
        for (int i=0; i < 256; i++) wpos[i] = -1;

        for (int i=0; (cur =  needle[i]) != '\0'; i++, len++) wpos[cur] = i;
        int p = 0, q = 0;
        while (true) {
            while (haystack[p] != '\0'
                    && needle[q] != '\0'
                    && haystack[p] == needle[q]) p++, q++;

            if ( needle[q] == '\0') {
                return haystack + p - q;
            }

            if (haystack[p] == '\0') {
                return NULL;
            }

            int npos = p - q + len;
            int move = wpos[haystack[npos]];
            q = 0;
            if (move < 0) {
                p++;
            } else {
                p = npos - move;
            }
        }
        return NULL;
    }
};

又写了次sunday算法,还是磕磕碰碰

第二轮 3.21

Implement strStr().

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

kmp、sunday都想不起来了,直接暴力吧,超时,然后加上一些条件能过应该是testcase不好,否则还是应该能造成超时:

class Solution {
public:
    int strStr(char *haystack, char *needle) {
        if (haystack == NULL || needle == NULL) {
            return -1;
        }
        
        int hlen = strlen(haystack);
        int nlen = strlen(needle);
        
        if (nlen > hlen) {
            return -1;
        }
        
        int hi = 0;
        int ni = 0;
        while (hi < (hlen - nlen + 1)) {
            int ti = hi;
            ni = 0;
            // try to campare start from haystack[ti] & needle[ni] (ti=hi, ni=0)
            while (needle[ni] != '\0' && haystack[ti] != '\0') {
                if (needle[ni] == haystack[ti]) {
                    ni++, ti++;
                } else {
                    break;
                }
            }
            if (needle[ni] == '\0') {
                return hi;
            }
            // start from next char
            hi++;
        }
        // not found
        return -1;
    }
};

 下面就超时:

class Solution {
public:
    int strStr(char *haystack, char *needle) {
        if (haystack == NULL || needle == NULL) {
            return -1;
        }
        
        for (int i=0; true; i++) {
            int ci = i;
            int ni;
            for(ni = 0; needle[ni] && haystack[ci]; ni++, ci++) {
                if (needle[ni] != haystack[ci]) {
                    break;
                }
            }
            if (needle[ni] == '\0') {
                return i;
            }
            if (haystack[i] == '\0') {
                break;
            }
        }
        
        // not found
        return -1;
    }
};

下面又不超时,到底是为什么?不是一样的方式么

class Solution {
public:
    int strStr(char *haystack, char *needle) {
        int i,j;  
        for (i = j = 0; haystack[i] && needle[j];) {  
            if (haystack[i] == needle[j]) {  
                ++i;  
                ++j;  
            } else {  
                i = i - j + 1;  
                j = 0;  
            }  
        }  
        return needle[j] ? -1 : (i - j);  
    }
};

 

一次Sunday算法:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int sunday(const char* src, const char* pattern) {
if (src == NULL || pattern == NULL) return -1;
int slen = strlen(src); int plen = strlen(pattern); int cpos = 0; int dict[256] = {0}; memset(dict, -1, sizeof(dict)); for (int i=0; i<plen; i++) { dict[pattern[i]] = i; } while (cpos + plen <= slen) { int i = 0; while (i < plen) { if (src[i+cpos] != pattern[i]) { break; } i++; } if (i == plen) { return cpos; } int move = dict[src[cpos + plen]]; // printf("tail char: %c\n", pattern[cpos + plen]); if (move < 0) { cpos = cpos + plen; } else { cpos = cpos + plen - move; } // printf("next pos:%d, %c\n", cpos, src[cpos]); } return -1; } int main(int argc, char* argv[]) { if (argc < 3) { printf("%s <src string> <pattern string>\n", argv[0]); return 0; } int idx = sunday(argv[1], argv[2]); if (idx < 0) { printf("not found pattern in src string\n"); return 0; } printf("match idx: %d, string from: %s\n", idx, argv[1] + idx); return 0; }

 可以再简化代码:

#include <iostream>
#include <cstdlib>

int sunday(const char* pattern, const char* str) {
    if (pattern == NULL || str == NULL) {
        return -1;
    }
    int slen = 0, plen = 0;

    while (pattern[plen] != '\0') plen++;
    while (str[slen] != '\0') slen++;
    
    int tbl[128];
    for (int i=0; i<128; i++) tbl[i] = -1;
    for (int i=0; i<plen; i++) tbl[pattern[i]] = i;
    
    int pi = 0, si = 0;
    
    while (si < slen) {
        while (str[si] == pattern[pi] && si < slen) si++, pi++;
        if (pi == plen) return si - plen;
        int nidx = plen - pi + si;
        int offset = tbl[str[nidx]];
        si = nidx - offset;
        pi = 0;
    }
    return -1;
}

int main() {
    char* pattern = "simple";
    char* str = "the example is a simple example.";
    
    
    int idx = sunday(pattern, str);
    if (idx < 0) {
        printf("not found\n");
    } else {
        printf("found at: %d\n", idx);
        printf("str:%s\n", str + idx);
    }
    system("pause");
    return 0;
}
si = nidx - offset;
这里当offset是负数时和非负数时其实是两种情况,但是因为将tbl数组初始化了为-1,所以nidx-offset其实相当于nidx + 1,刚刚可以把两种情况统一了。

感觉前面的暴力法写的复杂了,思路可以再清晰一些:
class Solution {
public:
    int strStr(string haystack, string needle) {
        int hlen = haystack.size();
        int nlen = needle.size();
        
        for (int i=0; i<hlen; i++) {
            int p = i, q = 0;
            if (hlen - i < nlen) {
                return -1;
            }
            while (p < hlen && q < nlen && haystack[p] == needle[q]) p++, q++;
            if (q == nlen) {
                return i;
            }
        }
        return nlen == 0 ? 0 : -1;
    }
};

 

posted @ 2014-06-06 20:06  卖程序的小歪  阅读(175)  评论(0编辑  收藏  举报