leetcode题记 8.字符串转换整数(atoi)

题目

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

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。

当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。

该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

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

说明

假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231,  231 − 1]。如果数值超过这个范围,qing返回  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) 。

来源:力扣(LeetCode)

题解

感觉这道题,因为输入样例的关系,所以无法避免的就是要对输入进行预处理。(去除空格,判断正负号,判断字符)

在到了数字字符串的部分的时候,和回文数的思路差不多,就是一个变量每次增大10倍然后加上新的一位。
要是说有什么地方改进算法可以加快速度的,私以为可能就只有在条件判断、正负号信息保存这些只能影响O(1)级别的地方进行改进了(我还是才疏学浅了TwT)。

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
41
class Solution {
public:
int myAtoi(string str) {
register unsigned int index = 0;
register long res = 0L;
bool flag = true;

while (str[index] == ' ') index++; // erase the blank spaces
if (!isdigit(str[index]) && str[index] != '-' && str[index] != '+') {
return int(res);
} // excluding while first is an alpha or something

if (str[index] == '-') { // mostly only judge once so save time
flag = false;
index++;
} else if (str[index] == '+') {
index++;
}

// can judge positive and negative parallelly, but operate twice
// if (str[index] == '-' || str[index] == '+') {
// flag = str[index] == '-'?false:true;
// index++;
// }

while (isdigit(str[index]) && res < 2147483648) {
res *= 10;
res += str[index++] - '0';
}
res *= flag?1:-1;

if (res > 2147483647) {
return 2147483647;
}
if (res < -2147483648) {
return -2147483648;
}

return res;
}
};

心得

这道题里面有一点投机取巧的成分在里面,比如将“经常运算但只有一个”的变量设置为register(寄存器变量)即可以让这段代码从16ms前进到4ms,但是在实际工程中并不能都这样,只有访问非常频繁、贯穿整个程序生命周期的变量再这样设置。当然致命的一点是,这只有c++才能用。

另一个投机取巧的的成分在于把溢出区间直接在编译的时候就准备好了,我看到许多题解在代码中比较溢出区间的时候还要现场运算2^31,这无疑会拖慢代码的运行。当然我还有看到更快的运算方法比如直接用1<<31这样的位运算来进行,这样也只会增加一些O(1)的运算时间。

结果

执行用时 : 4 ms, 在所有 C++ 提交中击败了95.07%的用户

内存消耗 : 8.4 MB, 在所有 C++ 提交中击败了87.79%的用户

Author: SmallXeon
Link: https://hexo.chensmallx.top/2019/07/24/leetcode-8-atoi/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
一些推广链接
几个便宜量大的小✈场: FASTLINK, YToo, 论坛邀请注册: ,
便宜量大但是稳定性不足的VPS: Virmach, 价格略贵但好用的VPN: , ,