字符按出现频率排序程序问题:同频字符未按ASCII升序排列
问题分析
原程序的核心问题在于qsort的比较函数cmpLetters仅根据字符出现频率排序,当两个字符频率相同时,未按照ASCII值从小到大的规则排序,导致同频字符的输出顺序不符合要求。
修复方案
修改cmpLetters函数的逻辑:
- 优先比较字符的出现频率,频率更小的排在前面;
- 若频率相同,则比较字符本身的ASCII值,ASCII值更小的排在前面。
修改后的比较函数代码:
int cmpLetters(const void *a, const void *b) { char c1 = *(char *)a; char c2 = *(char *)b; // 先按频率升序排序 if (times[c1] != times[c2]) { return times[c1] - times[c2]; } // 频率相同时按ASCII升序排序 return c1 - c2; }
完整修复代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int times[256]; int cmpLetters(const void *a, const void *b) { char c1 = *(char *)a; char c2 = *(char *)b; if (times[c1] != times[c2]) { return times[c1] - times[c2]; } return c1 - c2; } int main() { char letters[256]; int i, j, lnum; char s[1000]; fgets(s, sizeof(s), stdin); memset(times, 0, sizeof(times)); for (i = lnum = 0; s[i] != '\0'; i++) { // 统计阶段直接忽略空格,避免后续重复过滤 if (s[i] == ' ') { continue; } if (times[s[i]]++ == 0) { letters[lnum++] = s[i]; } } qsort(letters, lnum, sizeof(char), cmpLetters); for (i = 0; i < lnum; i++) { // 过滤fgets读取到的换行符 if (letters[i] != '\n') { printf("%c", letters[i]); } } printf("\n"); return 0; }
额外优化说明
- 原代码统计字符时未忽略空格,修复后在统计阶段直接跳过空格,减少后续输出时的过滤逻辑;
- 删除了原代码中未实际使用的
malloc内存分配代码,精简冗余逻辑; - 保留换行符过滤逻辑,避免
fgets读取的输入换行符被输出。
测试输入hello world,修复后的程序将输出预期结果dehrwol。
内容的提问来源于stack exchange,提问作者marvic pelato
相关产品推荐
相关产品推荐

