【C语言】水仙花数

ops/2024/9/22 18:02:20/

问题

水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数或阿姆斯壮数数(Armstrong number)。

它是指一个n位数(n≥3),它的每个位上的数字的n次幂之和等于它本身。例如:1^3 + 5^3 + 3^3 = 153,则153是一个水仙花数。对于三位数,水仙花数有153、370、371、407四个数。

这里我们扩大一点范围,假设水仙花数也可以小于三位数,只要一个n位数各位数字的n次方之和确好等于该数本身,我们就认为它是水仙花数,那么现在我们求出0~100000之间的所有“水仙花数”并输出。

整体分析

我们可以拆分一下我们到底要做哪几件事,就像你现在要煮一碗拉面,你可以将整个过程拆分为去买菜、备菜、煮面、吃、洗碗。解决这个问题,我们可以拆成生成0~100000的数组,求每个数是几位数(此时假设位数为n),求每个位上的数字的n次方之和(还可以进一步细分为求每位的n次方、求和两个动作),判断是否是水仙花数、打印这几件事。

具体分析

首先,生成0~100000的数字,这是最简单的,只需要一个循环语句:

int main()
{int i = 0;for(i=0; i<100000; i++){//具体的:计算位数n、求各位n次方和、判断是否为水仙花数和打印}return 0;
}

现在,我们就有了最外层的框架。

求几位数

怎么样才能得到这个数是几位数呢?这里我们可以用一种办法,我们知道,‘/’是整除,所以一个数/10的结果是去掉了最低位:

int a = 123;
int a = a/10;//将a整除10的结果重新赋值给a,现在a的值变为了12

那么,我们可以循环这个过程,定义一个变量count初始化为0,让我们的i每次/10后都count++,当i等于0的时候整除停止,此时我们得到的count就是位数:

看完这个图你一定就理解了吧。

得到各位上数字的count次方和

怎么做到这一点呢?我们知道一个数%10得到的就是最低位上的那个数字…等下,你不知道为什么?那我先浅浅讲解一下,已经知道的朋友可以跳过这段:

C语言中的%符号有两种主要用法:作为格式化字符串中的占位符和作为取模运算符,我们这里用到的是后一种。

%用作取模运算符时,表示整数除法的余数。例如,result = a % b; 计算的是 a 除以 b 的余数,并将结果赋值给 result。

使用%d时,确保对应的变量是整数类型(int),如果是长整型(long)则使用%ld或%Ld,短整型(short)使用%hd。

在进行取模运算时,要注意除数不能为零,否则会导致程序运行错误。

那么为什么一个数%10得到的就是最低位上的那个数字呢?我们这里说的“一个数”指的是十进制表示的一个数。%计算的是除之后的余数,%10就是除10后的余数,因为是十进制,所以剩在最低位上的就是无法达到10从而进位的数,所以也就是%10的余数。

这么说,应该能够理解了吧。

但是一次%10我们只能得到一个数字最低位的数啊,怎样才能把每一位的数字都拿到呢?其实我们的“武器”还是循环。而且我们还要借助上面刚提过的/10,因为将一个数/10就是整除10,而效果就是去掉了最低位,所以我们拿到一位、去掉一位、再拿一位、再去一位,不就能从低到高拿到每一位了吗?

既然我们要拿到每一位,并且要求它们的count次方的和,这时我们就创建一个变量sum,用来每轮循环存放这一位n次方的值,随着循环进行累加。

在C语言中我们想要求一个数的几次方,我们需要用到一个函数叫做pow,它的头文件为math.h,它所需的两个参数前者就是要求次方的数,后者就是几次方。

在了解这些后我们就能写出这个循环:

while (i)
{sum += pow(i % 10, count);i = i / 10;
}
陷阱

但是我的朋友,你先别高兴得太早,以上的代码其实有一个很难察觉的陷阱,这也是我在调试之后才找出来的:

对于后面这个求次方和的代码来说,此时的i在经过前一个循环后已经变成0而不是它原本的数字了。 那么我们根本都无法进入后面这个循环。其实,到最后判断的时候我们还要用到一次i的原始值。

那么怎么解决这个问题呢?

其实解决办法很简单,我们的目标就是不去改动i的值,那么我们只要在一开始就把i的值先赋给一个变量,并且在它需要变回i的值的时候,把i再赋一次给它就行了。所以以上两个循环应该改为:

for (i = 0; i < 100000; i++)
{int sum = 0;//这个要写在里面,否则对于每一个要检测的i来说,sum就不是从零开始了int count = 0;//这个也要写里面,理由同上。int tmp = i;//tmp接受i真正的值,替i进行变化,不用改动iwhile (tmp){count++;tmp = tmp / 10;}tmp = i;//让tmp重新变回i的值while (tmp){sum += pow(tmp % 10, count);tmp = tmp / 10;}
}
最终判断

现在,几位数(count)有了,各位上数字的count次方和有了,我们只需要拿和与我们的i进行比较判断就行了:

if (sum == i)printf("%d ", i);

完整代码参考:

在vs2022上运行效果:

那么,本篇博客内容到此就结束了,希望大家看完发现问题向我反馈,共同进步! 


http://www.ppmy.cn/ops/41636.html

相关文章

虹科Pico汽车示波器 | 免拆诊断案例 | 2010款凯迪拉克SRX车发动机无法起动

故障现象 一辆2010款凯迪拉克SRX车&#xff0c;搭载LF1发动机&#xff0c;累计行驶里程约为14.3万km。该车因正时链条断裂导致气门顶弯&#xff0c;大修发动机后试车&#xff0c;起动机运转有力&#xff0c;但发动机没有着机迹象&#xff1b;多起动几次&#xff0c;火花塞会变…

Windows下编译RTTR

虽然C11引入了RTTI、Metaprogramming 等技术&#xff0c;但C在Reflection编程方面依旧功能有限。在社区上&#xff0c;RTTR则提供了一套C编写的反射库&#xff0c;补充了C在Reflection方面的缺陷。 零、环境 操作系统Windows 11Visual StudioVisual Studio Community 2022 CMa…

安卓、iOS、iPad三端搞定,不再剧荒!

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 之前给大家推荐过各种看剧姿势&#xff0c;但很多苹果、平板端的小伙伴还是存在更好的需求体验&#xff0c;今天给大家推荐这款可以在安卓、iOS和平板上都能安装使用&#xff0c;不再剧…

腾讯中视频项目,日均收益1000+,简单搬运无限做,执行就有收入

兄弟们今天给大家分享的项目-腾讯视频的中视频计划项目&#xff0c;项目简单&#xff0c;低门槛&#xff0c;不需要考虑带货等问题&#xff0c;是2024年目前最火的变现赛道了。 因为目前来说的话&#xff0c;腾讯视频中视频是刚开始启动&#xff0c;是项目的红利期&#xff0c;…

el-table被点击行添加背景颜色

在 Element UI 的 el-table 组件中&#xff0c;你可以通过使用行样式 row-style 属性来为被点击的行添加颜色。首先&#xff0c;你需要在数据中定义一个对象来存储被点击行的索引&#xff0c;然后在 row-style 函数中根据这个索引来返回不同的样式。 以下是一个示例&#xff1…

link.click()时浏览器报错The file at ‘data:image/png;base64,iVBORw

代码如下&#xff1a; const dataURL canvas.toDataURL({format: "png",width: 400,height: 400, });const link document.createElement("a"); link.download new Date().getTime();link.href dataURL; document.body.appendChild(link); link.click…

(10)降落伞(一)

文章目录 前言 1 你将需要什么 2 连接到自动驾驶仪

Redis 基础之常用数据类型及命令

常用数据类型及命令 String&#xff08;字符串&#xff09;Hash&#xff08;哈希&#xff09;List&#xff08;列表&#xff09;Set&#xff08;集合&#xff09;zset ( sorted set&#xff1a;有序集合 )Redis setbit 命令HyperLogLogs ( 基数统计 ) Redis 比 Memcached 更优秀…