完数与盈数的计算题解

cpp 复制代码
#include <iostream>
using namespace std;
#include<vector>
int main() {

    vector<int> E(61, 0), G(61, 0);
    for (int i = 2; i < 61; i++) {
        int count = 0;
        for (int j = 1; j < i; ++j) {
            if (i % j == 0) {
                count += j;
            }
        }
        if (count == i) {
            E[i] = i;
        }
        if (count > i) {
            G[i] = i;
        }
    }
    cout << "E: ";
    for (int i = 0; i < 61; i++) {
        if (E[i] != 0) {
            cout << E[i] << " ";
        }
    }
    cout <<endl<< "G: ";
    for (int i = 0; i < 61; i++) {
        if (G[i] != 0) {
            cout << G[i] << " ";
        }
    }


    return 0;
}
// 64 位输出请用 printf("%lld")#define _CRT_SECURE_NO_WARNINGS
cpp 复制代码
#include<stdio.h>
#include <vector>
using namespace std;
int FactorSum(int i) {
    int res = 0;
    for (int j = 1; j < i; ++j) {
        if (i % j == 0) {
            res = res + j;
        }
    }
    return res;
}
int main() {
    vector<int>Evec;
    vector<int>Gvec;
    for (int i = 2; i <= 60; ++i) {
        if (i == FactorSum(i) ) {
            Evec.push_back(i);
        } else if (i < FactorSum(i)) {
            Gvec.push_back(i);
        }
    }

    vector<int>::iterator it;
    printf("E:");
    for (it = Evec.begin(); it != Evec.end() ; ++it) {
        printf(" %d", *it);
    }
    printf("\n");
    printf("G:");
    for (it = Gvec.begin(); it != Gvec.end(); ++it) {
        printf(" %d", *it);
    }
    printf("\n");
    return 0;

}

让我详细对比这两段代码:

第一段代码的问题

1. 数据结构使用不当

cpp 复制代码
vector<int> E(61, 0), G(61, 0);
  • 分配了61个元素的vector,用0填充
  • 只有少数位置有实际值(完全数:6, 28;盈数:12, 18, 20, 24, 30, 36, 40, 42, 48, 54, 56, 60)
  • 浪费内存:122个int中只有14个有用

2. 输出格式不规范

cpp 复制代码
cout << "E: ";
for (int i = 0; i < 61; i++) {
    if (E[i] != 0) {
        cout << E[i] << " ";  // 输出:E: 6 28 
    }
}
  • 数字之间有空格,但开头没有空格
  • 需要遍历整个61个元素的数组

3. 代码结构混乱

  • 计算逻辑和存储逻辑混在一起
  • 没有函数封装,代码复用性差

第二段代码的优点

1. 数据结构使用合理

cpp 复制代码
vector<int>Evec;
vector<int>Gvec;
  • 动态vector,只存储符合条件的数
  • 内存使用高效:只存储14个有效数字

2. 函数封装,代码模块化

cpp 复制代码
int FactorSum(int i) {
    int res = 0;
    for (int j = 1; j < i; ++j) {
        if (i % j == 0) {
            res = res + j;
        }
    }
    return res;
}
  • 将计算因子和的功能独立封装
  • 提高代码复用性和可读性
  • 便于测试和维护

3. 输出格式规范

cpp 复制代码
printf("E:");
for (it = Evec.begin(); it != Evec.end(); ++it) {
    printf(" %d", *it);  // 输出:E: 6 28
}
  • 每个数字前都有空格,格式统一
  • 使用迭代器遍历,更符合C++风格

4. 逻辑清晰

cpp 复制代码
if (i == FactorSum(i)) {
    Evec.push_back(i);
} else if (i < FactorSum(i)) {
    Gvec.push_back(i);
}
  • 条件判断清晰
  • 使用push_back动态添加元素

测试验证

完全数(Perfect Numbers):一个数等于它的所有真因子之和

  • 6 = 1+2+3 ✓
  • 28 = 1+2+4+7+14 ✓

盈数(Abundant Numbers):一个数小于它的所有真因子之和

  • 12 < 1+2+3+4+6 = 16 ✓
  • 18 < 1+2+3+6+9 = 21 ✓
  • 20 < 1+2+4+5+10 = 22 ✓
  • ...(共12个)

对比总结

对比项 第一段代码 第二段代码
内存使用 浪费(122个int) 高效(14个int)
代码结构 混乱 模块化
可读性 较差 优秀
可维护性
输出格式 不规范 规范
代码复用 有(FactorSum函数)

结论

第二段代码明显更好!

如果想用纯C++风格,可以稍作优化:

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

int FactorSum(int i) {
    int res = 0;
    for (int j = 1; j < i; ++j) {
        if (i % j == 0) {
            res += j;
        }
    }
    return res;
}

int main() {
    vector<int> Evec, Gvec;
    
    for (int i = 2; i <= 60; ++i) {
        int sum = FactorSum(i);
        if (i == sum) {
            Evec.push_back(i);
        } else if (i < sum) {
            Gvec.push_back(i);
        }
    }
    
    cout << "E:";
    for (int num : Evec) {
        cout << " " << num;
    }
    cout << endl;
    
    cout << "G:";
    for (int num : Gvec) {
        cout << " " << num;
    }
    cout << endl;
    
    return 0;
}

第二段代码的优势

  1. 数据结构使用合理(动态vector)
  2. 函数封装,代码模块化
  3. 输出格式规范统一
  4. 逻辑清晰,易于维护
  5. 内存使用高效
相关推荐
Dola_Zou2 小时前
工厂智能排产软件算法保护与按产线计费实战
算法·自动化·软件工程·软件加密
码匠许师傅3 小时前
【设计模式精讲】29.行为型模式总结与对比(Behavioral Patterns Summary)
c++·设计模式·uml
啦啦啦啦啦zzzz3 小时前
Logger的组装(c++20)
c++·算法·c++20
尾善爱看海4 小时前
前端算法与手写题集
前端·算法
繁星蓝雨5 小时前
C++的设计与演进大纲(如何从C语言一步步成长为C++)
c语言·开发语言·c++·c++历史·c++演进
程序员阿鹏5 小时前
为什么MySQL InnoDB选择B+树?
数据结构·数据库·b树·sql·mysql·算法·缓存
蒸蒸yyyyzwd5 小时前
机试学习笔记
c++·求职招聘
AI 思录5 小时前
Prompt 事故档案(八):日常表达被标为“待校准”,AI 的爹味语法从哪里来
大数据·人工智能·算法·prompt·用户体验·ai合规
月光船幽幽5 小时前
跨范式映射的稳定接口设计
人工智能·python·算法
handler016 小时前
【Linux】线程与虚拟内存的底层世界
linux·运维·服务器·c++·线程·虚拟地址空间·共享内存