Skip to content

Commit

Permalink
Implement strstr
Browse files Browse the repository at this point in the history
Signed-off-by: Leo Ma <[email protected]>
  • Loading branch information
begeekmyfriend committed Oct 4, 2017
1 parent fc50507 commit 48af54f
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
2 changes: 2 additions & 0 deletions 028_implement_strstr/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
all:
gcc -O2 -o test strstr.c
117 changes: 117 additions & 0 deletions 028_implement_strstr/strstr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#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;
}

0 comments on commit 48af54f

Please sign in to comment.