字符串转整数(atoi)

题目:实现 atoi ,将字符串转成整数。
该函数首先需要丢弃任意多的空格字符,直到找到第一个非空格字符为止;如果第一个非空字符是正号或者负号,选取该符号,并将其与后面尽可能多的连续的数字组合起来,这部分字符即为整数的值;如果第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。
字符串可以在形成整数的字符后面包括多余的字符,这些字符可以被忽略,他们对函数没有影响。
当字符串中的第一恶非空字符序列不是有效的整数,或字符串为空,或字符串仅包含空白字符时,则不进行转换。
或函数不能执行有效的转换,则返回0.

说明
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。如果数值超过可表示的范围,则返回 (231 − 1) 或 (−231) 。

示例1

1
2
输入:"42"
输出:42

示例2

1
2
输入:"   42"
输出:42

示例3

1
2
输入:"29292 asdddf"
输出:29292

示例4

1
2
输入:"afsfsf 442232"
输出:0

示例5

1
2
输入:"-91283472332"
输出:-2147483648
  • 通过题目和示例可以看出,在字符串转数字的过程中,只要遇到了不是数字或者正负号的符号时直接返回0.

解法
首先去掉字符左右的所有空格,再考虑字符串为空、第一个字符不是数字及正负号时直接返回0;如果第一个字符是正负号或者数字时,从第二个字符开始判断是否是数字,直到碰见不是数字,将此位置之前的所有字符截取并转换成数值。

CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
function atoiHandler(str) {
let deleteSpaceEndStr = str.replace(/^\s* | \s*$/g, ''),
strLen = deleteSpaceEndStr.length,
firStr = deleteSpaceEndStr.charAt(0),
notNumberIndex = 0,
atoiEndNumber;

if (!strLen || (!isNumberHander(firStr) && !isSignHandler(firStr)) return 0;

for (let i = 1; i < strLen; i++) {
notNumberIndex = i;
if (!isNumberHander(deleteSpaceEndStr.charAt(i))) break;
}

const splitStr = deleteSpaceEndStr.substring(0, notNumberIndex === strLen - 1 ? strLen : notNumberIndex);
// 第一个字符为正负号,第二个字符不是数字时会只截取第一个正负号值,因此在转换的时候需要判断一下
if (splitStr === 1 && (isSignHandler(splitStr))) {
atoiEndNumber = 0;
} else {
atoiEndNumber = parseInt(splitStr);
}

if (atoiEndNumber < -Math.pow(2, 31)) {
atoiEndNumber = -Math.pow(2, 31);
} else if (atoiEndNumber > Math.pow(2, 31) - 1) {
atoiEndNumber = Math.pow(2, 31) - 1;
}

return atoiEndNumber;
}

function isNumberHander(data) {
const dataCharCode = data.charCodeAt();
return (dataCharCode >= 48 && dataCharCode <= 57);
}

function isSignHandler(data) {
const dataCharCode = data.charCodeAt();
return (dataCharCode === 43 || dataCharCode === 45);
}

总结
这里需要注意的是:

  1. 当为空字符串
  2. 整个字符都为数字
  3. 第一个字符和第二个字符在同时为正负号的时候

此外,肯定还有有更好的方法,若老哥看了还忘不吝赐教……