微信关注公众号 [可回收BUG]
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/reverse-integer
这是来源于leetcode的一道题 “整数反转”,我们使用Rust来实现。
本次实战目的:
对 Option<T> 的取值函数的复习,与数字溢出的情况处理。
简单分析:
题目需要将数字反转过来,并保留当前的符号,数字类型是 i32 ,范围是[2147483647,-2147483648]。
对于数字的每一位可以通过不断对数字以10为除数取余和对剩下的数字被10整除的商再次进行取余,便可以依次取取出各位数字。
例如:
x = 123,
x % 10 = 3,x = floor(x / 10) = 12,
x % 10 = 2,x = floor(x/10) = 1,
x % 10 = 1。x = floor(x/10) = 0,停止。
分别依次得到3,2,1。
刚好第一个就可以获得目标结果数字的第一个,那么每次将其当前总结果乘10后与计算结果相加:
ret = 0
x % 10 = 3,ret = ret * 10 + 3 = 3
x % 10 = 2,ret = ret * 10 + 2 = 30 + 2
x % 10 = 1,ret = ret * 10 + 1 = 320 + 1
下面看一下代码:
fn reverse(x: i32) -> i32 {
let mut x = x;
let mut result:Option<i32> = Some(0);
loop {
if x == 0 {
break;
}
let tmp_num = x % 10;
x = x / 10;
result = result.unwrap().checked_mul(10);
if result.is_none() {
return 0_i32;
}
result = tmp_num.checked_add(result.unwrap());
if result.is_none() {
return 0_i32;
}
}
result.unwrap()
}
解释:
checked_mul(y) 乘法,可以由数字或者数字变量直接调用,需要明确数字类型,此函数结果会返回Option<T>类型,溢出范围则返回None。
checked_add(y) 加法,溢出后返回None。
unwrap() 获取枚举内的值,会获取枚举变量的所有权。
注意:
用IDE书写代码时,checked_mul 和 checked_add 并没有提示,我们看一下 i32 的方法实现:
#[lang = "i32"]
impl i32 {
int_impl! { i32, i32, u32, 32, -2147483648, 2147483647, "", "", 8, "0x10000b3", "0xb301",
"0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
"[0x12, 0x34, 0x56, 0x78]", "", "" }
}
i32 定义的方法内部是通过 int_impl! 宏展开的方法。int_impl! 宏内对checked_mul 定义了文档、文档内测试和方法体。
doc_comment! {
concat!("Checked integer multiplication. Computes `self * rhs`, returning `None` if
overflow occurred.
# Examples
Basic usage:
```
", $Feature, "assert_eq!(", stringify!($SelfT),
"::max_value().checked_mul(1), Some(", stringify!($SelfT), "::max_value()));
assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_mul(self, rhs: Self) -> Option<Self> {
let (a, b) = self.overflowing_mul(rhs);
if b {None} else {Some(a)}
}
}
文件:share/rust/rust_src/libcore/num/mod.rs
完