非常抱歉,之前的代码有问题。让我重新为你写一个完整的实现:
#include <stdio.h>
#include <string.h>
#include <limits.h>
#define MAX_LEN 10001
char* find_min_substring(char* S, char* P) {
int need[256] = {0}, window[256] = {0};
int s_len = strlen(S), p_len = strlen(P);
int left = 0, right = 0, min_len = INT_MAX, start = 0;
int count = 0; // 用于判断窗口中字符是否全部匹配
// 初始化需要匹配的字符计数
for (int i = 0; i < p_len; i++) {
need[(unsigned char)P[i]]++;
}
while (right < s_len) {
char r_char = S[right];
if (need[(unsigned char)r_char] > 0) {
window[(unsigned char)r_char]++;
if (window[(unsigned char)r_char] <= need[(unsigned char)r_char]) {
count++;
}
}
right++;
// 当窗口内的字符匹配时,开始收缩窗口
while (count == p_len) {
if (right - left < min_len) {
min_len = right - left;
start = left;
}
char l_char = S[left];
if (need[(unsigned char)l_char] > 0) {
window[(unsigned char)l_char]--;
if (window[(unsigned char)l_char] < need[(unsigned char)l_char]) {
count--;
}
}
left++;
}
}
static char result[MAX_LEN];
if (min_len == INT_MAX) return "";
strncpy(result, S + start, min_len);
result[min_len] = '\0';
return result;
}
int main() {
char S[MAX_LEN], P[MAX_LEN];
fgets(S, sizeof(S), stdin);
fgets(P, sizeof(P), stdin);
// 去掉换行符
S[strcspn(S, "\n")] = '\0';
P[strcspn(P, "\n")] = '\0';
char* result = find_min_substring(S, P);
printf("%s\n", result);
return 0;
}
### 重点解析:
1. **字符计数数组**:`need` 和 `window` 用于管理需要匹配的字符和当前窗口中匹配的字符。
2. **窗口滑动**:使用双指针 `left` 和 `right` 进行窗口滑动。当窗口满足要求后,通过调整 `left` 来缩小窗口。
3. **更新结果**:每次找到满足条件的窗口后,更新最小窗口长度 `min_len` 和起始位置 `start`。
4. **结果提取**:在 `result` 中提取并返回最终的最小子串结果。
通过这个代码,应该能准确地找到字符串 `S` 中包含子列 `P` 的最短子串。希望这能解决你的问题!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |