最近更新于 2024-05-06 07:58
题目
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/implement-strstr
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析及实现
这里是从算法的角度考虑问题,所以直接使用内置函数的方式就不考虑了,做出来也没有意义。
- 暴力

int strStr(char * haystack, char * needle)
{
if (strlen(needle) == 0)
{
return 0;
}
int haystack_len = strlen(haystack);
int needle_len = strlen(needle);
for (int i = 0; i <= haystack_len - needle_len; ++i)
{
static int j;
for (j = 0; j < needle_len; ++j)
{
if (haystack[i + j] != needle[j])
{
break;
}
}
if (j == needle_len)
{
return i;
}
}
return -1;
}
0 ms 是不可能等于 0 的,可能测试例子数量少,已经被四舍五入为 0 ms 了。

- KMP 算法
void kmp_init(const char *s, int *prefix, size_t size) {
prefix[0] = 0;
for (size_t i = 1; i < size; ++i) {
if (s[i] == s[prefix[i - 1]])
prefix[i] = prefix[i - 1] + 1;
else {
int j = i - 1;
while (prefix[j] > 0 && s[prefix[j]] != s[i])
j = prefix[j] - 1;
if (prefix[j] > 0)
prefix[i] = prefix[j] + 1;
else {
prefix[i] = (s[i] == s[0]);
}
}
}
}
int strStr(const char *src, const char *dest) {
if (!dest || !src)
return -1;
if (!*dest)
return 0;
size_t size = strlen(dest);
int *prefix = malloc(sizeof(int) * size);
kmp_init(dest, prefix, size);
size_t i, j;
for (i = j = 0; src[i] && j < size; ++i) {
if (dest[j] == src[i]) {
++j;
}
else if (j) {
while (prefix[j - 1] > 0 && dest[prefix[j - 1]] != src[i])
j = prefix[j - 1];
if (prefix[j - 1] > 0) {
j = prefix[j - 1] + 1;
}
else {
j = (dest[0] == src[i]);
}
}
}
free(prefix);
if (j < size)
return -1;
return i - size;
}

实现 strStr
