不使用<string.h>和<stdlib.h>实现字符数组及结构体数组字典序排序的问题求助
不用
<string.h>/<stdlib.h>实现结构体字符数组字典序排序 当然可以做到!咱们完全不用依赖标准库的字符串处理和内存分配函数,靠自己实现核心逻辑就能解决问题。先帮你排查下可能的逻辑漏洞,再给你一个可运行的完整方案。
核心问题分析
你之前尝试用ASCII值比较字符但没达到预期,大概率是这两个原因:
- 字符串比较不完整:只比较了单个字符,没遍历到字符串结束符
'\0',导致短字符串和长字符串(比如"app"和"apple")比较时出错; - 排序逻辑有漏洞:比如冒泡排序的循环边界设置错误,或者交换结构体时没有完整交换整个对象。
关键实现步骤
要完成这个需求,只需要自己实现两个核心功能:
- 替代
strcmp的字符串字典序比较函数 - 基础排序算法(这里用最易理解的冒泡排序演示,也可以换成效率更高的选择排序)
1. 自定义字符串比较函数my_strcmp
这个函数的逻辑和标准库strcmp一致:逐个比较两个字符串的字符ASCII值,直到遇到'\0'或字符不同,返回结果:
- 返回负数:第一个字符串小于第二个
- 返回0:两个字符串相等
- 返回正数:第一个字符串大于第二个
int my_strcmp(const char *a, const char *b) { while (*a != '\0' && *b != '\0') { if (*a != *b) { return *a - *b; } a++; b++; } // 处理一个字符串是另一个前缀的情况(比如"apple" vs "app") return *a - *b; }
2. 结构体定义与排序函数
假设你的结构体用于存储姓名,我们用冒泡排序来对结构体数组排序:
#include <stdio.h> // 只需要stdio做输入输出 typedef struct { char name[100]; } Person; // 冒泡排序结构体数组,按name字典序升序排列 void sort_persons(Person arr[], int count) { for (int i = 0; i < count - 1; i++) { int swapped = 0; // 标记是否发生交换,优化排序效率 for (int j = 0; j < count - 1 - i; j++) { if (my_strcmp(arr[j].name, arr[j+1].name) > 0) { // 完整交换两个结构体对象 Person temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; swapped = 1; } } if (!swapped) { break; // 没有交换说明数组已经有序,提前退出循环 } } }
3. 主函数测试
int main() { int n; printf("请输入人数:"); scanf("%d", &n); getchar(); // 吃掉输入n后的换行符,避免影响后续姓名输入 Person people[100]; // 假设最多处理100人,可按需调整数组大小 for (int i = 0; i < n; i++) { printf("请输入第%d个姓名:", i+1); fgets(people[i].name, sizeof(people[i].name), stdin); // 去掉fgets读取的换行符,避免输出时多一行空行 char *newline = people[i].name; while (*newline != '\0' && *newline != '\n') { newline++; } *newline = '\0'; } // 执行排序 sort_persons(people, n); // 输出排序结果 printf("\n排序后的姓名:\n"); for (int i = 0; i < n; i++) { printf("%s\n", people[i].name); } return 0; }
为什么这个方案能解决你的问题?
- 完整的字符串比较:
my_strcmp会遍历整个字符串直到结束符,处理了所有字符的比较,包括前缀匹配的特殊情况; - 正确的排序逻辑:冒泡排序的循环边界设置准确,加入了交换标记优化,确保数组能被完全排序;
- 无额外库依赖:只用到了
<stdio.h>做输入输出,完全符合你不用<string.h>和<stdlib.h>的要求。
可选优化:选择排序(减少交换次数)
如果你的数据量较大,冒泡排序的交换次数偏多,可以换成选择排序,它的交换次数更少,效率更高:
void sort_persons_select(Person arr[], int count) { for (int i = 0; i < count - 1; i++) { int min_idx = i; // 找到当前未排序部分的最小元素下标 for (int j = i + 1; j < count; j++) { if (my_strcmp(arr[j].name, arr[min_idx].name) < 0) { min_idx = j; } } // 交换当前元素和最小元素 Person temp = arr[i]; arr[i] = arr[min_idx]; arr[min_idx] = temp; } }
内容的提问来源于stack exchange,提问作者sameer dash
相关产品推荐
相关产品推荐

