leetcode 字符串转换整数 (atoi)(每日计划)

299 阅读4分钟

请你来实现一个 atoi 函数,使其能将字符串转换成整数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:

  • 如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
  • 假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
  • 该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。 注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0 。

提示:

  • 本题中的空白字符只包括空格字符 ' ' 。
  • 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231,  231 − 1]。如果数值超过这个范围,请返回  INT_MAX (231 − 1) 或 INT_MIN (−231) 。  

示例 1:

输入: "42"
输出: 42

示例 2:

输入: "   -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。
     我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

示例 3:

输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。

示例 4:

输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
     因此无法执行有效的转换。

示例 5:

输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 
     因此返回 INT_MIN (−231) 。

我的算法实现:

/**
 * @param {string} s
 * @return {number}
 */
var myAtoi = function (s) {
  s = s.trim();
  if (s.length === 0) return 0;
  const symbolObj = { "-": -1, "+": 1 };
  let digits = 0,
    symbol = 1;
  if (symbolObj[s[0]] !== undefined) {
    symbol = symbolObj[s[0]];
    s = s.substr(1);
  }
  for (let i = 0; i < s.length; i++) {
    const charCode = s.charCodeAt(i);
    if (charCode >= 48 && charCode <= 57) {
      digits = digits * 10 + charCode - 48;
      const exceed = Math.pow(2, 31);
      if (digits > (symbol > 0 ? exceed - 1 : exceed)) {
        return symbol > 0 ? exceed - 1 : -exceed;
      }
    } else break;
  }
  return digits * symbol;
};
  1. 拿到字符串的第一想法是先去除空格,于是使用了 trim 函数去除;
  2. 查看字符串的第一个字符是不是 - 或 + ,如果是的话就保存起来,并且把这个字符剔除,否则不处理;
  3. 循环过程中如果得到的 charCode 是在指定的范围内,那么就进行相应的运算,否则就退出;
  4. 如果满足条件(也就是是数字),那么运算完成以后判断一下当前运算的结果的范围是不是已经超过了,超过了就直接返回。
  5. 如果全部循环完成还没有返回也需要在这里进行返回。

今天也是使用的常规思维,想不到其他的,这就是我的悲哀呀,但是我还是相信越来越好。

官方的解析里面有这么一句话字符串处理的题目往往涉及复杂的流程以及条件情况,如果直接上手写程序,一不小心就会写出极其臃肿的代码。,我感觉就是说我这样的,我写的代码之所以效率不高,代码量大,就是因为没有仔细思考,直接上手撸的结果。

官方讲解:字符串转换整数 (atoi)

我看了官方的讲解,发现非常有意思,里面提到了一个自动机,也就是把每一种情况都捋清楚,比如当在刚开始遇到空格那么接下来出现的情况返回什么,真的非常棒的思路。评论区说到deterministic finite automaton, DFA,我表示不懂,只不过在学习设计模式的时候有一个跟这个有相似之处,好像是状态模式,跟策略有点相似,具体我也忘了,哈哈。看来设计模式又得复习了。

也有人直接使用正则表达式进行的(作者:QQqun902025048):

class Solution:
    def myAtoi(self, s: str) -> int:
        return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2**31 - 1), -2**31)

正则我在写的时候也想到了,只不过,只不过我的正则水平还达不到这样用。先放在这里,方便以后学习复习理解。


来源:力扣(LeetCode)