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

C++代码无法按数字出现次数排序,求问题排查与修正

问题需求

给定若干自然数,将这些数字十进制表示中出现的所有数字按出现次数升序排列;若出现次数相同,则数字较小的优先。

示例

输入:

5
124 229 1322 4 534

输出:

5 9 1 3 4 2
我的代码(无法实现预期排序)
#include <iostream>

using namespace std;

int v1[10],v2[10],lim,x,ok;

int main()
{
    cin>>lim;

    for(int i=1; i<=lim; i++)
    {
        cin>>x;

        while (x>0)
        {
            v1[x&10]++;
            v2[x%10]=x%10;
            x=x/10;
        }
    }
    while (!ok)
    {
        ok=1;

        for(int i=0; i<=lim; i++)
        {
            if(v1[i]>v1[i+1])
            {
                swap (v1[i],v1[i+1]);
                swap (v2[i],v2[i+1]);
                ok=0;
            }
        }
    }
    ok=0;
    while (!ok)
    {
        ok=1;

        for(int i=0; i<lim; i++)
        {
            if(v2[i]>v2[i+1])
                if(v1[i]==v1[i+1])
                    swap (v2[i],v2[i+1]);
        }
    }
    for (int i=0; i<=10; i++)
    {
        if(v2[i]!=0)
            cout<<v2[i]<<" ";
    }
}
问题分析与修正

你的代码存在几个核心问题:

  • 数字统计错误:v1[x&10]++ 用位运算&10替代取余%10是错误的(比如x=12时,12&10得8,12%10得2),导致计数完全混乱,必须改成v1[x%10]++。
  • 排序范围错误:排序的对象是0-9这10个数字,你却用输入的自然数个数lim作为循环边界,导致排序逻辑完全错位,循环范围应该固定为0到8(避免i+1越界)。
  • 排序逻辑割裂:分开两次冒泡排序的方式无法保证「次数升序优先,次数相同则数字升序」的规则,应该一次排序同时满足两个条件。
  • 输出逻辑缺陷:v2[i]!=0会漏掉数字0(如果输入包含0),应该判断v1[i]>0(即该数字确实出现过)。

修正后的代码

#include <iostream>
#include <algorithm>
using namespace std;

struct Digit {
    int num;    // 数字本身
    int count;  // 出现次数
} digits[10];

int main() {
    int lim, x;
    cin >> lim;

    // 初始化数字与计数
    for (int i = 0; i < 10; i++) {
        digits[i].num = i;
        digits[i].count = 0;
    }

    // 统计每个数字的出现次数
    for (int i = 1; i <= lim; i++) {
        cin >> x;
        // 单独处理输入为0的情况
        if (x == 0) {
            digits[0].count++;
            continue;
        }
        while (x > 0) {
            int d = x % 10;
            digits[d].count++;
            x /= 10;
        }
    }

    // 自定义排序:先按次数升序,次数相同则按数字升序
    sort(digits, digits + 10, [](const Digit& a, const Digit& b) {
        if (a.count != b.count) {
            return a.count < b.count;
        } else {
            return a.num < b.num;
        }
    });

    // 输出出现过的数字
    for (int i = 0; i < 10; i++) {
        if (digits[i].count > 0) {
            cout << digits[i].num << " ";
        }
    }
    cout << endl;
    return 0;
}

修正说明

  • 用结构体绑定数字和出现次数,排序时逻辑更清晰,避免两个数组分离导致的同步错误。
  • 使用标准库sort搭配lambda表达式,直接实现需求中的双重排序规则,比冒泡排序高效且不易出错。
  • 补充了输入为0的处理逻辑,避免遗漏数字0的统计。
  • 输出时仅打印出现过的数字,逻辑准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:17:42