C语言学习笔记20260611-水仙花数(2种解法)
一、题目要求
求出 0 ~ 100000 之间所有的水仙花数并输出。
水仙花数定义:
一个 n 位数 ,其各位数字的 n 次方和 等于自身。
示例:153 = 1³ + 5³ + 3³
二、解法一:标准库函数 pow版
1. 思路
-
遍历 0~100000 所有数字
-
先计算当前数字的总位数 n
-
逐位拆解数字,累加每一位的 n 次方
-
判断:次方和是否等于原数,相等即为水仙花数
2. 完整可运行代码
c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
// 功能:输出0~100000之间所有水仙花数
int main()
{
// 遍历区间所有数字
for (int i = 0; i <= 100000; i++)
{
// 临时变量,保存当前数字,避免修改原数i
int temp = i;
int len = 0;
// 1、计算当前数字的位数
while (temp != 0)
{
len++;
temp /= 10;
}
// 重置临时变量,重新拆解数字
temp = i;
int sum = 0;
// 2、计算各位数字的len次方之和
while (temp != 0)
{
int bit = temp % 10; // 取出末尾一位数字
sum += pow(bit, len); // 累加:当前位^位数
temp /= 10; // 去掉末尾一位
}
// 3、判断是否为水仙花数
if (sum == i)
{
printf("%d ", i);
}
}
return 0;
}
3. 优缺点
优点:代码简短、逻辑通用、新手易写
缺点:pow是浮点函数,极少数情况存在精度误差
三、解法二:自定义幂函数版(零精度误差)
1. 思路
手动实现整数次方函数,完全舍弃pow,全程整数运算,无精度丢失,考试最稳!
2. 完整可运行代码
c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 自定义整数幂函数:计算 base^exp(整数运算,无精度误差)
int my_pow(int base, int exp)
{
int res = 1;
for (int i = 0; i < exp; i++)
{
res *= base;
}
return res;
}
int main()
{
// 遍历0~100000所有数字
for (int i = 0; i <= 100000; i++)
{
int temp = i;
int len = 0;
// 1. 获取数字位数
while (temp != 0)
{
len++;
temp /= 10;
}
// 2. 计算各位n次方和
temp = i;
int sum = 0;
while (temp != 0)
{
int bit = temp % 10;
sum += my_pow(bit, len); // 调用自定义幂函数
temp /= 10;
}
// 3. 判断水仙花数
if (sum == i)
{
printf("%d ", i);
}
}
return 0;
}
3. 优缺点
优点:纯整数运算、零精度错误、考试竞赛首选
缺点:多定义一个函数,代码稍长
四、输出结果
Plain
1 2 3 4 5 6 7 8 9 153 370 371 407 1634 8208 9474 54748 92727 93084
五、总结
-
所有临时变量(位数、累加和)必须在循环内重置
-
求位数标准写法:
while(temp != 0) -
整数次方优先手写函数,避免pow浮点精度丢分
-
水仙花数判断顺序:求位数 → 求次方和 → 对比判断