本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
请你来实现一个 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 。
- 返回整数作为最终结果。
注意:
- 本题中的空白字符只包括空格字符
' '。 - 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。
输入:s = "42"
输出:42
解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
第 1 步:"42"(当前没有读入字符,因为没有前导空格)
^
第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
^
第 3 步:"42"(读入 "42")
^
解析得到整数 42 。
由于 "42" 在范围 [-231, 231 - 1] 内,最终结果为 42 。
解题思路
思路一
var myAtoi = function (s) {
// 去除首尾空格
s = s.trim()
if (!s) {
return 0
}
// 定义边界值
const INT_MAX = Math.pow(2, 31) - 1
const INT_MIN = -1 * Math.pow(2, 31)
// 取出第一个字符
let char = s.charAt(0)
// 如果第一个字符是正负号或者数字
if (char == "+" || char == "-" || (char >= "0" && char <= "9")) {
// 设立 cur 指针指向第二个字符
let cur = 1
// 找到截至点:首次遇到的非数字
while (s.charAt(cur) >= "0" && s.charAt(cur) <= "9") {
cur++
}
// 如果 cur 指针仍为1,说明其根本没有移动:即第二位不是数字,或者已经没有第二个字符了
if (cur == 1) {
// 前提是第一位是数字或者正负字符
// 如果第一位是正负号,则 return 0 如 "+-"、"+a"、"+"等
// 如果第一位是数字,则返回该数字即可,如 "1+"、"1a"、"1" 等
return (char == "+" || char == "-") ? 0 : char
}
// 取出数字字符串 并转为数字
const res = s.slice(0, cur) * 1
// 越界转换
if (res > INT_MAX) return INT_MAX
if (res < INT_MIN) return INT_MIN
// 正常输出
return res
}
// 第一个字符不是正负号或数字,返回 0
return 0
};
思路二
var myAtoi = function (s) {
let sign = '', res = []; //设置符号变量和结果字符串数组
s = s.trim(); //去除空格
let reg = /^[0-9]+$/; //判断是否为数字
for (let i = 0; i < s.length; i++) {
// 当前位 为 正负号 并且 下一位为数字 并且 结果字符串的长度小于0, 则把当前值赋值给sign
if ((s[i] === '-' || s[i] === '+') && reg.test(s[i + 1]) && res.length <= 0) {
sign = s[i];
continue;
}
if (!reg.test(s[i])) break; //碰到非数字的则结束循环
else res.push(s[i]);
}
if (res.length < 0) return 0; //如果结果字符数组为空,则说明没有满足条件的
let result = sign === '-' ? -Number(res.join('')) : Number(res.join(''));
if (result > Math.pow(2, 31) - 1) return Math.pow(2, 31) - 1; //判断是否结果是否溢出
if (result < Math.pow(-2, 31)) return Math.pow(-2, 31);
return result;
};