C语言中如何对存储高频词的Pair结构体按单词长度降序排序?
按单词长度从长到短排序Pair结构体的实现方案
嘿,这需求挺实用的!要实现把Pair结构体里的单词按长度从长到短排序,关键是要同步维护a(单词数组)和count(频率数组)的对应关系——毕竟每个单词和它的频率是绑定的,不能单独排序其中一个。下面给你一套清晰的实现步骤:
核心思路
我们可以借助C标准库的qsort(快速排序)来高效完成排序,但因为要同时关联两个数组,最稳妥的方式是先排序下标数组,再根据排序后的下标重新整理原数组的内容。这样既避免了直接操作原数组时的数据覆盖问题,也让排序逻辑更清晰。
具体实现步骤
1. 准备工作:头文件与结构体定义
先把必要的头文件和你的结构体定义写好,同时可以把结构体实例设为全局变量(方便排序函数访问,后续也可以用扩展方法替代全局变量):
#include <stdio.h> #include <stdlib.h> #include <string.h> // 你的Pair结构体定义 typedef struct pair { char * a[20000]; int count[32000]; } Pair; // 全局结构体实例,方便排序函数访问 Pair bag;
2. 统计有效单词数量
首先得确定a数组里实际存了多少个有效单词(毕竟数组大小是20000,但可能没填满)。假设你用NULL标记最后一个有效单词的末尾:
int n = 0; while (bag.a[n] != NULL) { n++; }
3. 创建并初始化下标数组
我们用一个下标数组记录每个单词的原始位置,排序这个下标数组就能间接实现原数组的排序,避免直接操作原数组的风险:
int indices[20000]; for (int i = 0; i < n; i++) { indices[i] = i; }
4. 编写qsort的比较函数
这个函数是排序的核心,我们按单词长度从长到短排序;如果长度相同,就按出现频率从高到低排序(和你的示例输出逻辑匹配):
int compare(const void *a, const void *b) { int idx1 = *(const int*)a; int idx2 = *(const int*)b; // 比较两个单词的长度 int len1 = strlen(bag.a[idx1]); int len2 = strlen(bag.a[idx2]); if (len1 != len2) { // 长的单词排在前面,qsort默认升序,返回len2-len1实现降序 return len2 - len1; } else { // 长度相同时,频率高的排在前面 return bag.count[idx2] - bag.count[idx1]; // 如果需要按字典序逆序排列,可以替换成: // return strcmp(bag.a[idx2], bag.a[idx1]); } }
5. 执行排序
调用qsort对下标数组进行排序,快速排序处理20000个元素效率很高:
qsort(indices, n, sizeof(int), compare);
6. 根据排序后的下标整理原数组
直接在原数组上交换会覆盖数据,所以先把排序后的内容存到临时数组,再复制回原结构体:
char *temp_a[20000]; int temp_count[32000]; for (int i = 0; i < n; i++) { temp_a[i] = bag.a[indices[i]]; temp_count[i] = bag.count[indices[i]]; } // 把临时数组内容复制回原结构体 memcpy(bag.a, temp_a, n * sizeof(char*)); memcpy(bag.count, temp_count, n * sizeof(int));
7. 测试验证
现在你可以像示例那样打印结果,就能看到符合要求的排序输出了:
printf("%d, %d, %d\n", bag.count[0], bag.count[1], bag.count[2]); // -> 8, 7, 3 printf("%s, %s, %s\n", bag.a[0], bag.a[1], bag.a[2]); // -> abbes, abbey, abhor
注意事项
- 确保
a数组最后有NULL标记,否则统计有效数量时会越界;如果有单独的长度计数变量,可以替换统计步骤。 - 不想用全局变量的话,GCC等编译器支持
qsort_r扩展,能把结构体指针作为参数传递给比较函数,彻底避免全局变量。 - 若单词长度相同需要其他排序逻辑(比如字典序),只需修改比较函数里长度相等时的返回值即可。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

