一起学Rust-实战leetcode(五)

微信关注公众号 [可回收BUG]

上期练习:一起学Rust-实战leetcode(四)

给出一个 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

本文分享自微信公众号 - 可回收BUG(way-of-full-stack)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏趣谈前端

5分钟教你用nodeJS手写一个mock数据服务器

对于前端开发者而言,javascript正扮演着越来越重要的地位,它不仅能为浏览器端赋能,在web服务器方面也有很大的价值(我们可以用nodeJS来写服务端代码...

11210
来自专栏Rude3Knife的后端开发专栏

Python学习笔记(四)——高级特性

本文是廖雪峰的Python教程的笔记,主要是摘抄一些重点。所以我把他划分到转载里。侵删。

7910
来自专栏Web行业观察

函数式编程中的数组问题

好久没讲技术了,先回忆一下啥是函数式编程(FP)吧,比如FP要求使用表达式,不允许出现语句,这样更接近自然语言。

6220
来自专栏Rude3Knife的后端开发专栏

Python学习笔记(六)——面向对象编程

class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,继承的概念我们后面再讲,通常,如...

6210
来自专栏Rude3Knife的后端开发专栏

Python学习笔记(七)——进程和线程

很多时候,子进程并不是自身,而是一个外部进程。我们创建了子进程后,还需要控制子进程的输入和输出。

7020
来自专栏Rude3Knife的后端开发专栏

Python学习笔记(一)——Python基础

本文是廖雪峰的Python教程的笔记,主要是摘抄一些重点。所以我把他划分到转载里。侵删。

9610
来自专栏Rude3Knife的后端开发专栏

Python学习笔记(二)——IO输入输出

本文是廖雪峰的Python教程的笔记,主要是摘抄一些重点。所以我把他划分到转载里。侵删。

5910
来自专栏Rude3Knife的后端开发专栏

[剑指offer题解][Java]连续子数组的最大和

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

13310
来自专栏A周立SpringCloud

StackOverFlowError 常见原因及解决方法

每一个 JVM 线程都拥有一个私有的 JVM 线程栈,用于存放当前线程的 JVM 栈帧(包括被调用函数的参数、局部变量和返回地址等)。如果某个线程的线程栈空间被...

55520
来自专栏Rude3Knife的后端开发专栏

Python学习笔记(五)——函数式编程

成功!说明变量f现在已经指向了abs函数本身。直接调用abs()函数和调用变量f()完全相同。

7310

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励