开启我的LeetCode刷题日记:8. 字符串转换整数 (atoi)

475 阅读3分钟

「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战

编程世界总是离不了算法

最近在看框架源码时,会有很多算法的实现逻辑,有时候会感到吃力

于是决定蹭着假期,加强算法和数据结构相关的知识

那怎么提升呢?

其实我知道算法这东西没有捷径,多写多练才能提升,于是我开启我的LeetCode刷题之旅

第一阶段目标是:200道,每天12

为了不乱,本系列文章目录分为三部分:

  1. 今日题目:xxx
  2. 我的思路
  3. 代码实现

今天题目:8. 字符串转换整数 (atoi)

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:

读入字符串并丢弃无用的前导空格 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。 如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。 返回整数作为最终结果。 注意:

本题中的空白字符只包括空格字符 ' ' 。 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。  

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/st… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的思路

官方的主要规则可以概况为:

无视开头空格 返回有符号整数 无视整数部分后的字符 范围在32位内(含) 其他情况返回0 各位JSer,你品,你细品,这个转换规则,是不是很眼熟?

谜底揭晓,它就是JavaScript世界中的parseInt()这一API的转换规则。

逻辑梳理 现在来简要阐述下parseInt()的转换规则,关于这个API的具体描述,可以查看MDN上的这篇文档。

parseInt(string, radix):

string:要被解析的值。如果参数不是一个字符串,则将其转换为字符串。字符串开头的空白符将会被忽略。 radix(可选):需要转换的进制,介于 2 到 36。 返回值: 如果被解析参数的第一个字符无法被转化成数值类型,则返回NaN。 对比下题意,发现

无视开头空格(满足) 返回有符号整数(满足) 无视整数部分后的字符(满足) 范围在32位内(含)(不满足) 其他情况返回0(不满足) 那么只要有针对性的处理下不满足的条件即可。

范围在32位内(含) 只需简单地将API转换后的值与临界值进行对比就行。

if (number < Math.pow(-2, 31) || number > Math.pow(2, 31) - 1) { return number < Math.pow(-2, 31) ? Math.pow(-2, 31) : Math.pow(2, 31) - 1; } 其他情况返回0 很显然,API的返回值如果是NaN,则说明无法正常转换,所以只需将返回值和NaN进行比较即可。

注意,NaN和NaN并不全等,所以各位JSer不能使用全等操作符(===),而该使用isNaN()函数来比较。

if(isNaN(number)) { return 0; } 小细节 在使用parseInt(string, radix)这一API时,如果不传入radix参数,会有两种特殊情况:

如果字符串 string 以"0x"或者"0X"开头, 则基数是16 (16进制). 如果字符串 string 以"0"开头, 基数是8(八进制)或者10(十进制),那么具体是哪个基数,取决与ECMAScript的版本。 所以,通常建议在使用parseInt()这一API时,都明确给出期望的进制数,这是一个良好的编程习惯。

代码实现

/**
 * @param {string} str
 * @return {number}
 */
var myAtoi = function(str) {
    const number = parseInt(str, 10);

    if(isNaN(number)) {
        return 0;
    } else if (number < Math.pow(-2, 31) || number > Math.pow(2, 31) - 1) {
        return number < Math.pow(-2, 31) ? Math.pow(-2, 31) : Math.pow(2, 31) - 1;
    } else {
        return number;
    }
};

总结

实现方式其实有很多,这里仅供参考~

由于刚开始刷题,也不知道从哪里刷好,如果前辈们有好的建议,希望不吝赐教,感谢🌹