【C++编程】水仙花数问题详解:三种解法对比与优化
创作时间:
作者:
@小白创作中心
【C++编程】水仙花数问题详解:三种解法对比与优化
引用
CSDN
1.
https://m.blog.csdn.net/2201_75539691/article/details/144857979
在程序设计中,“水仙花数”是一个带有数学特色的热点题目。这个题目最核心的思路在于如何分解三位数,并检查它是否满足水仙花数的定义。通过进一步分析、优化,我们不仅能学习到原理,还可以探索于实现与效率之间的平衡点。本文将从题目解读、个人实现、老师做法、思路对比与优化,以及指向临水仙花数更学机。
题目描述
2029:【例4.15】水仙花数
题目要求如下:
- 计算 100 到 999 中的水仙花数
如果三位数 ( ABC ) 满足以下条件:
A B C = A 3 + B 3 + C 3 ABC = A^3 + B^3 + C^3ABC=A3+B3+C3
则称 ( ABC ) 为水仙花数。
例如:三位数 153 ,其三位系数分别是:
1 3 + 5 3 + 3 3 = 1 + 125 + 27 = 153 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 15313+53+33=1+125+27=153
则 153 是水仙花数。
输入: - 无需输入
输出: - 由小到大输出满足条件的数,每个数单独一行。
示例输出:
153
370
371
407
个人做法
个人的做法如下:
#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;
}
思路分析
- 通过
for
循环遍历 [100, 999] 范围内的所有数字,以判断每个数字是否是水仙花数。 - 通过循环中的初始化:
- 用临时变量
m
存储当前数字,无需直接操作原数。 - 定义
count
用于积累各位系数立方和。
- 通过内部
while
循环:
- 取位系数:通过
m % 10
获得最低位; - 计算立方值并积累:通过
j * j * j
直接计算立方值; - 清除最低位:通过
m /= 10
,将数字左移一位;循环至数字为 0 为止。
- 检查立方积累和是否等于原数,如等,则输出。
优势
- 简洁直观: 计算每个位系数立方直接通过三次乘法完成,避免使用更复杂的函数。
- 处理简单: 通过循环直接完成数字分解、积累立方和,无需额外函数调用,更实用。
不足之处
- 总处理时间复杂度为 ( O(n \times d) ),对于三位数,( d ) 是 3,因此复杂度为实际上是存在优化空间的,如果可直接计算各位,则可省去一些循环操作。
- 输出格式比较基本,如需更好看的输出,可选择增加分隔符。
老师的做法
老师的代码如下:
#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;
}
思路分析
- 核心比较:使用
pow
函数计算立方:
老师的做法并没有用直接乘法计算立方,而是使用了标准库中的
pow
函数。这样做的好处是:在基础程序教学中,比较直观,学生能学习标准函数的应用;同时使用
pow
计算任意次方,优质显而易见。 - 居有化简:进一步生成临时变量,直接取位计算,治理系统优化:
基于基础计算源,老师用
tmp
分解,保留原数,从维护和计算的规范性方面,有较高的规范性和应用性。
优势
- 可读性更好: 使用
pow
函数,明确表达了“次方”的概念,更便于基础教学和理解。 - 通用性更强: 如需更改次方,可直接修改为
pow(tmp % 10, n)
,适配与任意次方计算,更具通用性。
不足
- 性能突出较少: 使用
pow
函数导致调用源库,效率上不如直接乘法。在计算量不大时,注意不显著;但如若展开到更大的数据量,远不如乘法计算的效率高。
对比和优化
实现方式对比
方式 核心思想 优势 不足
个人做法 通过三次乘法直接计算立方 性能高,逻辑简洁,极对化 相对基础学生,学习成本较高
老师做法 使用pow函数计算立方 可读性好,通用性强 性能不如直接乘法,有调用源库的增加费用
优化思路和操作
在经典做法上,如下作举可能更加高效和实用:
1. 直接分解数字的各位
使用数学运算分解数字的各位,无需循环:
#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. 展开至任意位数水仙花数
通过使用函数展开计算任意位数的水仙花数:
#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;
}
小结
通过对个人和老师做法的分析,我们能看到:
- 核心思想相同: 个人和老师都是通过数字分解和立方积累,实现水仙花数的检查。
- 实现途径带有小差异: 个人的做法更重视性能,老师做法更重视可读性。
- 优化思考: 通过直接分解数字和展开至任意位数,可以更加高效和通用。
在实际经验中,可根据场景和需求选择最适合的方案,例如教学中选择通过性更强的方案,而在效率优先的场景下,可选择性能更高的直接乘法。求真时,始终是计算积累的深层探索!
热门推荐
四反潜望长焦镜头设计原理与SYNOPSYS软件实现
修复Windows Wi-Fi 6 AX201 160 MHz驱动程序错误的方法
打印图片怎么去掉黑底变得清晰 详细教程介绍
如何将自定义快捷方式添加到 Windows 11 或 10 上下文菜单
给孩子补钙能促进身高增长吗?
戊唑醇杀菌剂使用指南:防治对象、用量及注意事项详解
肌少症怎麼辦?跟著骨科醫師這樣吃、這樣動
全国青少年无人机大赛的参赛流程
三款防脱发、祛痘产品添加禁用原料
奇门遁甲的博弈智慧:职场女性都在用的科学决策术!
东部中心被列为广州“三核”之一,增城迎“双轮驱动”重大发展机遇
人民币对越南盾汇率最新变化趋势解析
武汉地铁行李携带规定及禁止携带物品清单!
黑白无常的真实名称及其历史渊源探讨
红薯可以进微波炉吗?微波烹饪的家居小技巧
在红尘中修行:从《天幕红尘》看人性的多维镜像
国医大师林毅教授支招冬季养生
植物组织培养霉菌、真菌污染处理 外植体消毒代替升汞培养皿灭菌
战网国服预约方法 战网国服账号注册+客户端下载一站式教程
产品经理如何维护旧版本
一粒桑葚五味药?揭秘桑葚5个特点、5大药用功效,这些人别乱吃
OSI模型_TCP/IP模型_五层模型
庄股营业部有哪些特征?
三湖慈鲷的饲养及市场现状
提升学生研究能力的21世纪化学类专业研究生教育
溪流钓鱼技巧与溪流竿的选择(掌握溪流钓鱼的方法与技巧)
科兴疫苗事件:一场暴露决策与监管体系深层危机的全民反思
换断桥窗户多少钱一平方,预算与价值的平衡之道
离婚后孩子应该怎么相处
赡养人都有什么的权利和义务