一起学Rust-实战leetcode(六)

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

题目截图来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/string-to-integer-atoi/

这是来源于leetcode的一道题 “字符串转换整数(atoi)”,我们使用Rust来实现。

本次实战目的:

字符串字节向量引用的使用,类型转换,数字的边界处理,字符串取片段,。

简单分析:

题目讲的比较清晰。直接讲一下思路:

将字符串转换为utf8的字节类型,那么数字、符号等会转换为对应的ascii码,则通过对于单字节的数字、符号进行遍历比对。

至于转换为整数至少有两种方法,其一可以使用字符串截取片段来获取一段完整数字,通过 i32::from_str 转换,并可以处理溢出的异常。

其二可以使用checked_mul 和 checked_add 对每一个获取到的数字进行计算,这里类似上一期的整数翻转功能。

本次练习使用第一种方法。

直接上代码,随后进行解析:

fn my_atoi(s: String) -> i32 {
    // 获取字节数组引用
    let bytes = s.as_bytes();

    // 字符串截取的起始和结束
    let (mut start, mut idx) = (0, 0);
    // 是否为负数
    let mut negative = false;

    // 是否遇到数字,是否遇到符号
    let (mut num, mut symbol) = (false, false);
    //定义各字符的ascii码遍历
    let (zero, plus, sub, nine, space) = (b'0', b'+', b'-', b'9', b' ');

    while idx < bytes.len() {

        let ascii = bytes[idx];
        //当遇到符号或者数字后,存在其他字符,则停止。
        if (num || symbol) && (ascii == space || ascii == plus || ascii == sub) {
            break;
        }

        if ascii == space || ascii == plus || ascii == sub {
            start += 1;
            if ascii == plus || ascii == sub {
                symbol = true;
            }
            if ascii == sub {
                negative = true;
            }
        }

        if ascii >= zero && ascii <= nine {
            num = true;
        }

        if ascii != space && ascii != plus && ascii != sub && (ascii < zero || ascii > nine) {
            break;
        }

        idx += 1;
    }
    
    // 截取开始和结束相等的情况 一定是0
    if start == idx {
        return 0;
    }

    use std::str::FromStr;
    //截取字符串,转换失败时会返回ParseIntError
    if let Ok(v) = i32::from_str(&s[start..idx]) {
        if negative {
            return v.checked_mul(-1).unwrap_or(std::i32::MIN);
        }
        return v;
    }

    if negative {
        return std::i32::MIN;
    }
    return std::i32::MAX;
}

as_bytes() 获取String内的Vec<u8>向量的引用。

可以通过 b'0' 定义u8类型的字节码,但是不能使用双引号的 b"0" ,是因为它是 &[u8; 1] 类型,不适合用在这里。

注意:使用 i32::from_str() 需要引入std::str::FromStr,参数需要传入&str类型。如此获取的字符串发生转换异常时则一定是溢出的情况。

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

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

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

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

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券