Skip to content

Commit 48af54f

Browse files
Implement strstr
Signed-off-by: Leo Ma <[email protected]>
1 parent fc50507 commit 48af54f

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed

028_implement_strstr/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
all:
2+
gcc -O2 -o test strstr.c

028_implement_strstr/strstr.c

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
#if 0
6+
int strStr(char *haystack, char *needle)
7+
{
8+
if (haystack == NULL || needle == NULL) {
9+
return -1;
10+
}
11+
12+
int hlen = strlen(haystack);
13+
int nlen = strlen(needle);
14+
15+
/* haystack < needle */
16+
if (hlen < nlen) {
17+
return -1;
18+
}
19+
20+
if (nlen == 0) {
21+
return 0;
22+
}
23+
24+
/* boyer-moore bad character */
25+
int i, j;
26+
int bad_steps[128];
27+
for (i = 0; i < 128; i++) {
28+
bad_steps[i] = nlen;
29+
}
30+
31+
for (i = 0; i < nlen; i++) {
32+
bad_steps[needle[i]] = nlen - 1 - i;
33+
}
34+
35+
/* boyer-moore good suffix */
36+
int *good_steps = malloc(nlen * sizeof(int));
37+
for (i = 0; i < nlen; i++) {
38+
good_steps[i] = nlen;
39+
for (j = i - 1; j >= 0; j--) {
40+
if (!memcmp(needle + i, needle + j, nlen - i)) {
41+
good_steps[i] = i - j;
42+
break;
43+
}
44+
}
45+
}
46+
47+
char *p = haystack + nlen - 1;
48+
char *q = needle + nlen - 1;
49+
char *r = p;
50+
while (p - haystack < hlen) {
51+
int step = 0;
52+
for (i = 1; i <= nlen && *p == *q; i++) {
53+
if (q == needle) {
54+
return p - haystack;
55+
}
56+
if (good_steps[nlen - i] > step) {
57+
step = good_steps[nlen - i];
58+
}
59+
p--;
60+
q--;
61+
}
62+
63+
if (i == 1 && bad_steps[*p] > step) {
64+
step = bad_steps[*p];
65+
}
66+
r += step;
67+
p = r;
68+
q = needle + nlen - 1;
69+
}
70+
71+
return -1;
72+
}
73+
#endif
74+
75+
static int strStr(char *haystack, char *needle)
76+
{
77+
int i, j, found = 1;
78+
unsigned int hlen = strlen(haystack);
79+
unsigned int nlen = strlen(needle);
80+
81+
if (nlen == 0) {
82+
return 0;
83+
}
84+
85+
/* Brute force */
86+
for (i = 0; i < hlen; i++) {
87+
if (haystack[i] == needle[0]) {
88+
for (j = 1; j < nlen; j++) {
89+
if (i + j < hlen) {
90+
if (haystack[i + j] != needle[j]) {
91+
found = 0;
92+
break;
93+
}
94+
} else {
95+
return -1;
96+
}
97+
}
98+
if (found) {
99+
return i;
100+
}
101+
}
102+
found = 1;
103+
}
104+
105+
return -1;
106+
}
107+
108+
int main(int argc, char **argv)
109+
{
110+
if (argc != 3) {
111+
fprintf(stderr, "Usage: ./test heystack needle\n");
112+
exit(-1);
113+
}
114+
115+
printf("%d\n", strStr(argv[1], argv[2]));
116+
return 0;
117+
}

0 commit comments

Comments
 (0)