题目
实现C/C++中的atoi函数myAtoi(string s),将字符串转换为一个32位有符号整数。
算法myAtoi(string s)描述如下:
- 读取并忽略开头的空格。
- 检查下一个字符(不在最后)是
'-'或'+'。如果是,请将此字符读入。这决定最终结果是负还是正。如果两者都不存在,则假设结果为正。 - 读取下一个字符,直到到达下一个非数字字符或输入末尾。字符串的其余部分将被忽略。
- 将这些数字转换为整数(即
"123"->123,"0032"->32)。如果未读取任何数字,则整数为“0”。根据需要更改符号(从步骤2开始)。 - 如果整数超出32位有符号整数范围
[-231, 231^-1],则对整数进行钳位,使其保持在该范围内。具体来说,小于-231的整数应箝位为-231,大于231 - 1的整数应该箝位为231 - 1。 - 返回整数作为最终结果。
注意:
-
只有空格字符“”被视为空白字符。
-
不要忽略除前导空格或数字后字符串的其余部分之外的任何字符。
示例 1:
输入: s = "42"
输出: 42
说明:插入符号是当前读取器的位置。
步骤 1: "42" (带下划线的字符是读入的字符,插入符号是当前读取器的位置。)
^
步骤 2: "42" (没有字符,因为既没有'-'也没有'+')
^
步骤 3: "42" ("42" 被读入)
^
解析的整数是42。
由于42在[-231, 231^-1]范围内,最终结果为42。
示例 2:
输入: s = " -42"
输出: -42
说明:
步骤 1: " -42" (读取并忽略前导空格)
^
步骤 2: " -42" (已读取“-”,因此结果应为负值)
^
步骤 3: " -42" ("42" 被读入)
^
解析的整数是 -42.
由于-42在[-231, 231^-1]范围内,最终结果为-42。
示例 3:
输入: s = "4193 with words"
输出: 4193
说明:
步骤 1: "4193 with words" (不读取字符,因为没有前导空格)
^
步骤 2: "4193 with words" (没有读取字符,因为既没有“-”也没有“+”)
^
步骤 3: "4193 with words" (读入“4193”;读取停止,因为下一个字符是非数字)
^
解析的整数是 4193.
由于4193在[-231, 231^-1]范围内,最终结果为4193。
思路
- 记录符号
- 逐个记录数字
- 逆序组装
function myAtoi(s: string): number {
let value = 0;
let sign = 1;
const numbers = [];
let start = false; // 开始检测了,用于标记数字后是字符串需要终止
for (let i = 0; i < s.length; i++) {
const char = s[i];
const val = parseInt(char); // 是否为数字
if (isNaN(val)) {
if (start) break; // 数字 + 字符 => 终止
if (char === ' ') continue;
if (char === '-') {
start = true;
sign = -1;
continue;
}
if (char === '+') {
start = true;
sign = 1;
continue;
}
break; // 以非数字开始
} else {
if (!start) start = true;
numbers.push(val);
}
}
value = sign * numbers.reverse().reduce((sum, d, i) => sum + d * Math.pow(10, i), 0);
if (value < -Math.pow(2, 31)) return -Math.pow(2, 31);
if (value > Math.pow(2, 31) - 1) return Math.pow(2, 31) - 1;
return value;
}