C语言字符串每k位循环提取功能的代码问题及优化咨询
代码问题说明
- 问题1:结果数组未做全局维护。你在每次循环内都将写入指针p初始化为0,新提取的字符会直接覆盖之前已经写入
result的内容,且全程没有给result追加字符串结束符\0,最终puts(result)会输出乱码。 - 问题2:元素删除逻辑错误。正向遍历删除元素时,删除当前索引的元素后,后续所有元素的索引都会前移1位,你仍然按原始索引做
j%k判断、且仅给j加1的处理方式,会导致漏删、错删元素。 - 问题3:循环终止后剩余的长度小于k的字符串,没有追加到结果末尾,不符合需求的拼接规则。
- 额外注意:函数名
remove和C标准库函数重名,运行可能出现异常,建议重命名。
修复后的可运行代码
#include <stdio.h> #include <string.h> void remove_char(char *str, unsigned int index) { char *src; for (src = str+index; *src != '\0'; ++src) { *src = *(src+1); } *src = '\0'; } int main() { char number[100]; char result[100]; int k, res_p = 0; // 全局维护结果的写入指针 printf("Enter a string: "); scanf("%s", number); printf("Enter a key: "); scanf("%d", &k); while (strlen(number) >= k) { int len = strlen(number); // 先提取所有第k位字符 for (int i = k-1; i < len; i += k) { result[res_p++] = number[i]; } // 反向遍历删除已提取字符,避免索引偏移影响判断 for (int i = ((len - 1)/k)*k; i >= k-1; i -=k) { remove_char(number, i); } } // 追加剩余不足k位的字符 int left_len = strlen(number); for (int i = 0; i < left_len; i++) { result[res_p++] = number[i]; } result[res_p] = '\0'; // 补字符串结束符 puts(result); return 0; }
更高效的实现方案
这个需求本质是约瑟夫环按出列顺序拼接结果,不需要每次修改原字符串移动字符,直接计算每次出列的索引即可,逻辑更简单,出错概率更低:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char number[100], result[100]; int k, res_p = 0; printf("Enter a string: "); scanf("%s", number); printf("Enter a key: "); scanf("%d", &k); int n = strlen(number); int *used = (int*)calloc(n, sizeof(int)); // 标记字符是否已被提取 int pos = 0, count = 0; while (res_p < n) { if (!used[pos]) count++; if (count == k) { result[res_p++] = number[pos]; used[pos] = 1; count = 0; } pos = (pos + 1) % n; } result[res_p] = '\0'; puts(result); free(used); return 0; }
内容的提问来源于stack exchange,提问作者Sgg8
相关产品推荐
相关产品推荐

