From 48af54f721f5ecc8d7d6088a64964175eb5780a7 Mon Sep 17 00:00:00 2001 From: Leo Ma Date: Wed, 4 Oct 2017 08:34:14 +0800 Subject: [PATCH] Implement strstr Signed-off-by: Leo Ma --- 028_implement_strstr/Makefile | 2 + 028_implement_strstr/strstr.c | 117 ++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 028_implement_strstr/Makefile create mode 100644 028_implement_strstr/strstr.c diff --git a/028_implement_strstr/Makefile b/028_implement_strstr/Makefile new file mode 100644 index 0000000..2feaab7 --- /dev/null +++ b/028_implement_strstr/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O2 -o test strstr.c diff --git a/028_implement_strstr/strstr.c b/028_implement_strstr/strstr.c new file mode 100644 index 0000000..b314b50 --- /dev/null +++ b/028_implement_strstr/strstr.c @@ -0,0 +1,117 @@ +#include +#include +#include + +#if 0 +int strStr(char *haystack, char *needle) +{ + if (haystack == NULL || needle == NULL) { + return -1; + } + + int hlen = strlen(haystack); + int nlen = strlen(needle); + + /* haystack < needle */ + if (hlen < nlen) { + return -1; + } + + if (nlen == 0) { + return 0; + } + + /* boyer-moore bad character */ + int i, j; + int bad_steps[128]; + for (i = 0; i < 128; i++) { + bad_steps[i] = nlen; + } + + for (i = 0; i < nlen; i++) { + bad_steps[needle[i]] = nlen - 1 - i; + } + + /* boyer-moore good suffix */ + int *good_steps = malloc(nlen * sizeof(int)); + for (i = 0; i < nlen; i++) { + good_steps[i] = nlen; + for (j = i - 1; j >= 0; j--) { + if (!memcmp(needle + i, needle + j, nlen - i)) { + good_steps[i] = i - j; + break; + } + } + } + + char *p = haystack + nlen - 1; + char *q = needle + nlen - 1; + char *r = p; + while (p - haystack < hlen) { + int step = 0; + for (i = 1; i <= nlen && *p == *q; i++) { + if (q == needle) { + return p - haystack; + } + if (good_steps[nlen - i] > step) { + step = good_steps[nlen - i]; + } + p--; + q--; + } + + if (i == 1 && bad_steps[*p] > step) { + step = bad_steps[*p]; + } + r += step; + p = r; + q = needle + nlen - 1; + } + + return -1; +} +#endif + +static int strStr(char *haystack, char *needle) +{ + int i, j, found = 1; + unsigned int hlen = strlen(haystack); + unsigned int nlen = strlen(needle); + + if (nlen == 0) { + return 0; + } + + /* Brute force */ + for (i = 0; i < hlen; i++) { + if (haystack[i] == needle[0]) { + for (j = 1; j < nlen; j++) { + if (i + j < hlen) { + if (haystack[i + j] != needle[j]) { + found = 0; + break; + } + } else { + return -1; + } + } + if (found) { + return i; + } + } + found = 1; + } + + return -1; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test heystack needle\n"); + exit(-1); + } + + printf("%d\n", strStr(argv[1], argv[2])); + return 0; +}