一起学Rust-实战leetcode(五)
- 2019 年 10 月 7 日
- 筆記
微信关注公众号 [可回收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
完