本文主要是介绍2021.6.26 8. 字符串转换整数 (atoi)(字符串转整数的数值溢出问题),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
注:
分正数和负数的情况讨论会不会越界。
题目:
请你来实现一个 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 。 返回整数作为最终结果。
注意:
本题中的空白字符只包括空格字符 ’ ’ 。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。
示例 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 。
提示:
0 <= s.length <= 200
s 由英文字母(大写和小写)、数字(0-9)、’ ‘、’+’、’-’ 和 ‘.’ 组成
题解:
**一旦涉及整数的运算,我们需要注意溢出。**本题可能产生溢出的步骤在于推入、乘以 10 操作和累加操作都可能造成溢出。
对于溢出的处理方式通常可以转换为 INT_MAX 的逆操作。比如判断某数乘以 10 是否会溢出,那么就把该数和 INT_MAX 除以 10 进行比较。
时间复杂度:O(n),其中 n 为字符串的长度。我们只需要依次处理所有的字符,处理每个字符需要的时间为 O(1)。
空间复杂度:O(n),temp用了O(n)大小(实际上可以省去这个O(n),直接在s上修改即可)。
class Solution {
public:int myAtoi(string s) {string temp;int flag=1;int result=0;for(int i=0;i<s.size();i++){if(s[i]==' '){continue;}else{temp=s.substr(i);break;}}int index=0;if(temp[index]=='-'){flag=-1;}if(temp[index]=='-'||temp[index]=='+'){index++;}for(int i=index;i<temp.size();i++){if(temp[i]>='0'&&temp[i]<='9'){//分正数和负数的情况讨论会不会越界。if(flag==1&&(result>INT_MAX/10||(result==INT_MAX/10&&temp[i]-'0'>=7))){return INT_MAX; }if(flag==-1&&(-result<INT_MIN/10||(-result==INT_MIN/10&&temp[i]-'0'>=8))){return INT_MIN;}result=result*10+(temp[i]-'0');}else{break;}}return result*flag;}
};
这篇关于2021.6.26 8. 字符串转换整数 (atoi)(字符串转整数的数值溢出问题)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!