【C++】2029:【例4.15】水仙花数



博客主页:[小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C++


文章目录



💯前言

  • 在程序设计中,"水仙花数"是一个带有数学特色的热点题目。这个题目最核心的思路在于如何分解三位数,并检查它是否满足水仙花数的定义。通过进一步分析、优化,我们不仅能学习到原理,还可以探索于实现与效率之间的平衡点。本文将从题目解读、我的实现、老师做法、思路对比与优化,以及指向临水仙花数更学机。
    C++ 参考手册

💯题目描述

2029:【例4.15】水仙花数

题目要求如下:

  • 计算 100 到 999 中的水仙花数
    如果三位数 ( ABC ) 满足以下条件:
    A B C = A 3 + B 3 + C 3 ABC = A^3 + B^3 + C^3 ABC=A3+B3+C3
    则称 ( ABC ) 为水仙花数。

例如:三位数 153 ,其三位系数分别是:
1 3 + 5 3 + 3 3 = 1 + 125 + 27 = 153 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153 13+53+33=1+125+27=153

则 153 是水仙花数。

输入:

  • 无需输入

输出:

  • 由小到大输出满足条件的数,每个数单独一行。

示例输出:

text 复制代码
153
370
371
407

💯我的做法

我的做法如下:

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

int main()
{
    for (int i = 100; i <= 999; i++) // 遍历所有三位数
    {
        int m = i; // 存储当前数字
        int count = 0; // 积累各位系数的立方和

        while (m)
        {
            int j = m % 10; // 取位:下一个位系数
            count += j * j * j; // 计算立方并积累
            m /= 10; // 清除最低位
        }

        if (count == i) // 检查积累立方和是否等于原数字
            cout << i << endl; // 输出
    }

    return 0;
}

思路分析

  1. 通过 for 循环遍历 [100, 999] 范围内的所有数字,以判断每个数字是否是水仙花数。
  2. 通过循环中的初始化:
    • 用临时变量 m 存储当前数字,无需直接操作原数。
    • 定义 count 用于积累各位系数立方和。
  3. 通过内部 while 循环:
    • 取位系数:通过 m % 10 获得最低位;
    • 计算立方值并积累:通过 j * j * j 直接计算立方值;
    • 清除最低位:通过 m /= 10,将数字左移一位;循环至数字为 0 为止。
  4. 检查立方积累和是否等于原数,如等,则输出。

优势

  • 简洁直观: 计算每个位系数立方直接通过三次乘法完成,避免使用更复杂的函数。
  • 处理简单: 通过循环直接完成数字分解、积累立方和,无需额外函数调用,更实用。

不足之处

  • 总处理时间复杂度为 ( O(n \times d) ),对于三位数,( d ) 是 3,因此复杂度为实际上是存在优化空间的,如果可直接计算各位,则可省去一些循环操作。
  • 输出格式比较基本,如需更好看的输出,可选择增加分隔符。

💯老师的做法

老师的代码如下:

cpp 复制代码
#include <iostream>
#include <cmath> // 引入函数 pow

using namespace std;

int main()
{
    for (int i = 100; i <= 999; i++) // 遍历所有三位数
    {
        int tmp = i; // 临时处理数字
        int ret = 0; // 积累各位系数立方和

        while (tmp)
        {
            ret += pow(tmp % 10, 3); // 取位和立方,使用pow函数
            tmp /= 10; // 清除最低位
        }

        if (ret == i) // 检查积累立方和是否等于原数
            cout << i << endl; // 输出
    }

    return 0;
}

思路分析

  1. 核心比较:使用 pow 函数计算立方:

    老师的做法并没有用直接乘法计算立方,而是使用了标准库中的 pow 函数。这样做的好处是:在基础程序教学中,比较直观,学生能学习标准函数的应用;同时使用 pow 计算任意次方,优质显而易见。

  2. 居有化简:进一步生成临时变量,直接取位计算,治理系统优化:

    基于基础计算源,老师用 tmp 分解,保留原数,从维护和计算的规范性方面,有较高的规范性和应用性。

优势

  • 可读性更好: 使用 pow 函数,明确表达了"次方"的概念,更便于基础教学和理解。
  • 通用性更强: 如需更改次方,可直接修改为 pow(tmp % 10, n) ,适配与任意次方计算,更具通用性。

不足

  • 性能突出较少: 使用 pow 函数导致调用源库,效率上不如直接乘法。在计算量不大时,注意不显著;但如若展开到更大的数据量,远不如乘法计算的效率高。

💯对比和优化

实现方式对比

方式 核心思想 优势 不足
我的做法 通过三次乘法直接计算立方 性能高,逻辑简洁,极对化 相对基础学生,学习成本较高
老师做法 使用 pow 函数计算立方 可读性好,通用性强 性能不如直接乘法,有调用源库的增加费用

优化思路和操作

在经典做法上,如下作举可能更加高效和实用:

1. 直接分解数字的各位

使用数学运算分解数字的各位,无需循环:

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

int main()
{
    for (int i = 100; i <= 999; i++)
    {
        int a = i / 100;       // 百位
        int b = (i / 10) % 10; // 十位
        int c = i % 10;        // 个位

        if (i == a * a * a + b * b * b + c * c * c)
            cout << i << endl;
    }
    return 0;
}

这种做法可以直接获取各位,避免伴随调用和循环,效率更高。

2. 展开至任意位数水仙花数

通过使用函数展开计算任意位数的水仙花数:

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

// 检查水仙花数
bool isArmstrong(int n)
{
    int sum = 0, tmp = n;
    int digits = log10(n) + 1; // 位数

    while (tmp)
    {
        sum += pow(tmp % 10, digits); // 次方积累
        tmp /= 10;
    }
    return sum == n;
}

int main()
{
    for (int i = 100; i <= 999; i++)
    {
        if (isArmstrong(i))
            cout << i << endl;
    }
    return 0;
}

💯小结

通过对我和老师做法的分析,我们能看到:

  1. 核心思想相同: 我和老师都是通过数字分解和立方积累,实现水仙花数的检查。
  2. 实现途径带有小差异: 我的做法更重视性能,老师做法更重视可读性。
  3. 优化思考: 通过直接分解数字和展开至任意位数,可以更加高效和通用。

在实际经验中,可根据场景和需求选择最适合的方案,例如教学中选择通过性更强的方案,而在效率优先的场景下,可选择性能更高的直接乘法。求真时,始终是计算积累的深层探索!



相关推荐
XLYcmy2 小时前
分布式练手:Server
c++·windows·分布式·网络安全·操作系统·c·实验源码
学习前端的小z1 天前
【C++】B2089 数组逆序重存放
c
charlie1145141912 天前
如何使用 OpenCV 扫描图像、查找表和时间测量
c++·opencv·学习·计算机视觉·c·教程
charlie1145141912 天前
Linux Kernel Programming4
linux·c·makefile·内核开发·内核日志
学习前端的小z3 天前
【C++】探索一维数组:从基础到深入剖析
c
oioihoii3 天前
VSCode下配置Blazor环境 & 断点调试Blazor项目
ide·python·c
肆——3 天前
PTA数据结构作业一
c
charlie1145141914 天前
从0开始的Opencv之旅(到尝试构建一个图像编辑器):0,opencv demo
c++·图像处理·opencv·学习·c·教程
这题怎么做?!?5 天前
const与constexpr
c++·c