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

C++动态分配内存实现Kaprekar自数无输出,静态数组正常

解决Kaprekar自数动态数组无输出的问题

嘿,我看到你在实现D.R. Kaprekar自数的时候遇到了一个奇怪的问题——静态数组能正常输出结果,但换成动态分配内存的版本就没反应了。咱们来一步步拆解问题出在哪,以及怎么修复:

问题根源:数组越界访问导致未定义行为

先看你的d()函数,它的作用是计算一个数加上自身各位数字的和,这个结果必然大于原数。当你遍历i从0到9999时,最大的d(i)是多少呢?算一下:i=9999时,d(9999)=9999+9+9+9+9=10035。

但你动态分配的数组只有10000个元素,索引范围是0~9999。这时候访问arr[10035]就属于数组越界访问,这是C++里的未定义行为——它可能会破坏数组的内存结构,甚至覆盖程序里的其他变量(比如循环计数器、内存管理的元数据),导致后面的输出循环根本没法正常执行,自然就没输出了。

而你用静态数组时能正常运行,大概率是因为静态数组的大小设得足够大(比如超过10035),刚好避开了越界问题。

修复方案:分配足够大的动态数组

要解决这个问题,我们只需要先计算出d(i)的最大值,然后分配对应大小的动态数组,确保所有数组访问都在合法范围内。这里提供两种修复思路:

思路1:调整原逻辑的数组大小

基于你原来的代码逻辑,修改数组大小并修正循环:

#include<iostream>
using namespace std;

int d(int num) {
    int dn = num;
    while (num != 0) {
        dn += num % 10;
        num = num / 10;
    }
    return dn;
}

int main() {
    const int MAX_NUM = 9999;
    // 计算最大的d(n):9999的各位和是36,所以最大值是9999+36=10035
    const int MAX_D_VALUE = MAX_NUM + 9*4;
    // 分配足够大的数组,覆盖所有可能的d(n)结果
    int* arr = new int[MAX_D_VALUE + 1];

    // 初始化数组:1~MAX_NUM的位置设为对应数值,其余设0
    for (int i = 0; i <= MAX_D_VALUE; i++) {
        arr[i] = (i <= MAX_NUM) ? (i + 1) : 0;
    }

    // 标记非自数:遍历1~MAX_NUM,将对应的d(n)位置设为0
    for (int n = 1; n <= MAX_NUM; n++) {
        int dn = d(n);
        if (dn <= MAX_D_VALUE) {
            arr[dn] = 0;
        }
    }

    // 输出自数:筛选出未被标记的数
    for (int i = 1; i <= MAX_NUM; i++) {
        if (arr[i-1] > 0) {
            cout << i << endl;
        }
    }

    delete[] arr;
    return 0;
}

思路2:用更清晰的标记数组逻辑

如果觉得原逻辑有点绕,可以改用标记数组的方式,代码可读性更高:

#include<iostream>
using namespace std;

int d(int num) {
    int dn = num;
    while (num != 0) {
        dn += num % 10;
        num = num / 10;
    }
    return dn;
}

int main() {
    const int MAX_NUM = 9999;
    const int MAX_D_VALUE = MAX_NUM + 9*4;
    // 动态分配标记数组,初始化为0(0表示是自数,1表示非自数)
    int* is_non_self = new int[MAX_D_VALUE + 1]();

    // 标记所有非自数
    for (int n = 1; n <= MAX_NUM; n++) {
        int dn = d(n);
        if (dn <= MAX_D_VALUE) {
            is_non_self[dn] = 1;
        }
    }

    // 输出所有自数
    cout << "1到9999之间的Kaprekar自数:" << endl;
    for (int n = 1; n <= MAX_NUM; n++) {
        if (is_non_self[n] == 0) {
            cout << n << endl;
        }
    }

    delete[] is_non_self;
    return 0;
}

关键总结

  • 动态数组版本无输出的核心原因是数组大小不足,导致越界访问触发未定义行为。
  • 解决这类问题的关键是先明确数组需要容纳的最大元素值,再分配对应大小的内存,避免越界。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 17:52:50