Hi,大家好,这里是炼手Rust专栏,我是xiaoK,今天来看个小问题:阿姆斯特朗数。
提问
如果一个数有 N 位且每一位数字的 N 次方之和等于它自己,那么这个数就叫阿姆斯特朗数。
例:
- 9 是阿姆斯特朗数,因为 9 = 9^1 = 9
- 10 不是阿姆斯特朗数,因为 10 != 1^2 + 0^2 = 1
- 153 是阿姆斯特朗数,因为: 153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153
- 154 不是阿姆斯特朗数,因为: 154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190
编写代码来确定一个数字是否是阿姆斯特朗数。
模板:
pub fn is_armstrong_number(num: u32) -> bool {
todo!("true if {num} is an armstrong number")
}
分析
按照计算方法,首先要确定的是当前这个数有多少位,也就是值 N,然后再计算每一位数字的 N 次方。
解决方案
pub fn is_armstrong_number(num: u32) -> bool {
let mut count = 0;
let mut digit = num;
while digit != 0 {
digit /= 10;
count += 1;
}
let mut sum:u64 = 0;
digit = num;
while digit != 0 {
sum = sum.wrapping_add(u64::from((digit % 10).wrapping_pow(count)));
digit /= 10;
}
u64::from(num) == sum
}
Trick
rust针对数学运算(加减乘除)有很多特定的方法,例如在加法中,有saturating_add和wrapping_add。saturating_add会在数字溢出的时候,保留数字的最大值。wrapping_add会在数字溢出的时候,循环计算该值。举个例子:
println!("{}", u8::MAX.saturating_add(2));
println!("{}", u8::MAX.wrapping_add(2));
println!("{}", i8::MAX.saturating_add(2));
println!("{}", i8::MAX.wrapping_add(2));
该程序输出:
255
1
127
-127