From b4ebda4fc94e4505ff268ec0e08bd951911e26c5 Mon Sep 17 00:00:00 2001 From: C_W Date: Tue, 10 Dec 2024 16:52:12 +1100 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A00028=E5=AE=9E=E7=8E=B0strStr?= =?UTF-8?q?=20C=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0028.实现strStr.md | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md index e0cb123e..63a08d96 100644 --- a/problems/0028.实现strStr.md +++ b/problems/0028.实现strStr.md @@ -1456,6 +1456,70 @@ public int[] GetNext(string needle) } ``` +### C: + +> 前缀表统一右移和减一 + +```c + +int *build_next(char* needle, int len) { + + int *next = (int *)malloc(len * sizeof(int)); + assert(next); // 确保分配成功 + + // 初始化next数组 + next[0] = -1; // next[0] 设置为 -1,表示没有有效前缀匹配 + if (len <= 1) { // 如果模式串长度小于等于 1,直接返回 + return next; + } + next[1] = 0; // next[1] 设置为 0,表示第一个字符没有公共前后缀 + + // 构建next数组, i 从模式串的第三个字符开始, j 指向当前匹配的最长前缀长度 + int i = 2, j = 0; + while (i < len) { + if (needle[i - 1] == needle[j]) { + j++; + next[i] = j; + i++; + } else if (j > 0) { + // 如果不匹配且 j > 0, 回退到次长匹配前缀的长度 + j = next[j]; + } else { + next[i] = 0; + i++; + } + } + return next; +} + +int strStr(char* haystack, char* needle) { + + int needle_len = strlen(needle); + int haystack_len = strlen(haystack); + + int *next = build_next(needle, needle_len); + + int i = 0, j = 0; // i 指向主串的当前起始位置, j 指向模式串的当前匹配位置 + while (i <= haystack_len - needle_len) { + if (haystack[i + j] == needle[j]) { + j++; + if (j == needle_len) { + free(next); + next = NULL + return i; + } + } else { + i += j - next[j]; // 调整主串的起始位置 + j = j > 0 ? next[j] : 0; + } + } + + free(next); + next = NULL; + return -1; +} +``` +