美文网首页优美编程
字符串转换整数 (atoi)

字符串转换整数 (atoi)

作者: 小遁哥 | 来源:发表于2019-12-08 00:46 被阅读0次

    从字符串里提取有效数,大于2^31 − 1 返回 2^31 − 1,小于−2^31,返回−2 ^ 31。

    输入: "42"
    输出: 42
    
    输入: "   -42"
    输出: -42
    解释: 第一个非空白字符为 '-', 它是一个负号。
         我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
    
    输入: "   +42"
    输出: 42
    
    输入: "4193 with words"
    输出: 4193
    解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
    
    输入: "words and 987"
    输出: 0
    解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
         因此无法执行有效的转换。
    

    最初的解法

    var myAtoi = function(str) {
        let result = +(str.trim().match(/^[-+]?\d+/g) || [])[0];
        if(result){
            if(result > 2**31 - 1){
                return 2**31 - 1;
            }
            else if(result < -(2**31)){
                return -(2**31);
            }
            return result;
        }
        
        return 0;
    };
    

    match 函数可能返回null

    +null 会返回 0

    -(2**31) 的()不加会报一个晦涩的语法错误,大概是造成了代码执行的二意性。

    Uncaught SyntaxError: Unary operator used immediately before exponentiation expression. Parenthesis must be used to disambiguate operator precedence
    
    上面的问题在于用了太多的判断,其实parseInt函数可以很好的起到过滤作用,但我认为用正则起到很好的锻炼作用

    参考后的解法

    var myAtoi = function(str) {
          let number = +parseInt(str);
          let result = number
            ? Math.max(Math.min(number, 2 ** 31 - 1), -(2 ** 31))
            : 0;
          return result;
        };
    

    parseInt 可能返回 NaN,而Boolean(NaN) 返回false

    这也意味着 逻辑进入Math.max(Math.min()) 后,result不会时NaN

    问题

    您会觉得 Math.max(Math.min()) 这种写法不易读吗?

    有趣的事

    最初的解法是有let isNumber = !Number.isNaN(result); 这段代码,我以为+null 会返回 NaNBoolean(NaN) 返回false,然后删掉了这行代码,结果发现+null 会返回 0,写文章的过程中,认知发生了两次变化。

    相关文章

      网友评论

        本文标题:字符串转换整数 (atoi)

        本文链接:https://www.haomeiwen.com/subject/ctmpgctx.html