You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言字符频率排序程序求助:平局时无法按ASCII值升序排列

字符按频率排序:修复次数相同时的ASCII升序问题

问题描述

需要实现一个程序,按以下规则输出文本中的字符:

  • 忽略空格
  • 字符按出现次数升序排列
  • 若出现次数相同,按ASCII值较小的字符优先输出

示例输入hello world,正确输出应为dehrwol,但当前程序输出hewrdol,原因是次数相同时未按ASCII升序排序。

问题根源

原代码的cmpLetters比较函数仅判断了字符出现次数的差异,没有处理次数相同的场景。当次数相等时,qsort的排序结果是不确定的(依赖底层实现),导致不符合ASCII升序的要求。

解决方案

修改cmpLetters函数,在次数相同时比较字符的ASCII值,确保ASCII小的字符排在前面:

int cmpLetters(const void* a, const void* b)
{
    char charA = *(char*)a;
    char charB = *(char*)b;
    // 先比较出现次数,次数少的在前
    if (times[charA] != times[charB]) {
        return times[charA] - times[charB];
    }
    // 次数相同时,ASCII值小的在前
    return charA - charB;
}

额外优化点

原代码在统计字符时没有忽略空格,而是在输出时跳过,逻辑不够严谨。建议在统计阶段直接排除空格和换行符(因为fgets会读取输入末尾的换行):

for (i = lnum = 0; s[i] != '\0'; i++) {
    // 忽略空格和换行符
    if (s[i] == ' ' || s[i] == '\n') {
        continue;
    }
    if (times[s[i]]++ == 0) {
        letters[lnum++] = s[i];
    }
}

修改后的完整代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int times[256];

int cmpLetters(const void* a, const void* b)
{
    char charA = *(char*)a;
    char charB = *(char*)b;
    if (times[charA] != times[charB]) {
        // 次数升序:次数少的返回负数,排在前面
        return times[charA] - times[charB];
    }
    // ASCII升序:值小的返回负数,排在前面
    return charA - charB;
}

int main()
{
    char letters[256];
    int i, j, k, 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] == ' ' || s[i] == '\n') {
            continue;
        }
        if (times[s[i]]++ == 0) {
            letters[lnum++] = s[i];
        }
    }

    // 按规则排序
    qsort(letters, lnum, sizeof(char), cmpLetters);

    // 输出结果
    for (i = 0; i < lnum; i++) {
        printf("%c", letters[i]);
    }
    printf("\n");

    return 0;
}

测试验证

输入hello world,程序输出dehrwol,符合预期。

内容的提问来源于stack exchange,提问作者edmung vunxh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:55:16