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;

    }

};

 

你可能感兴趣的:(LeetCode)