[炼手Rust]阿姆斯特朗数

69 阅读1分钟

Hi,大家好,这里是炼手Rust专栏,我是xiaoK,今天来看个小问题:阿姆斯特朗数。

main-qimg-6202dfe5b75025dc0e19f9ee1ce99638-lq.jpg

提问

如果一个数有 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

  1. rust针对数学运算(加减乘除)有很多特定的方法,例如在加法中,有saturating_addwrapping_addsaturating_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