💓 博客主页:倔强的石头的CSDN主页
📝Gitee主页:倔强的石头的gitee主页
⏩ 文章专栏:C++经典例题
期待您的关注
目录
一、问题描述
LCR 192. 把字符串转换成整数 (atoi) - 力扣(LeetCode)
在编程中,经常会遇到将字符串转换为整数的需求,就像标准库中的 atoi
函数一样。
本题要求实现一个 myAtoi
函数,将输入的字符串转换为 32 位有符号整数,具体规则如下:
- 读入字符串并丢弃无用的前导空格。
- 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。确定最终结果是负数还是正数。如果两者都不存在,则假定结果为正。
- 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
- 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
- 如果整数数超过 32 位有符号整数范围
[−2^31, 2^31 − 1]
,需要截断这个整数,使其保持在这个范围内。具体来说,小于−2^31
的整数应该被固定为−2^31
,大于2^31 − 1
的整数应该被固定为2^31 − 1
。
二、解题思路
为了实现 myAtoi
函数,我们可以按照以下步骤进行:
- 忽略前导空格:从字符串的开头开始,跳过所有的空格字符,直到遇到第一个非空格字符。
- 处理符号:检查第一个非空格字符是否为
+
或-
,如果是+
,则结果为正数;如果是-
,则结果为负数;如果没有符号,则默认结果为正数。 - 转换数字:从符号字符之后开始,依次读取数字字符,将其转换为整数。如果遇到非数字字符,则停止读取。
- 溢出处理:在转换数字的过程中,需要检查是否会发生溢出。如果结果超出了 32 位有符号整数的范围,则需要截断结果。
三、代码实现
#include <iostream>
#include <string>
#include <climits>
class Solution {
public:
int myAtoi(std::string str)
{
int flag = 1; // 正负号
int i = 0; // 下标
int ret = 0; // 结果
int size = str.size();
// 忽略前导空格
while (i < size && str[i] == ' ') {
++i;
}
// 处理符号
if (i < size && str[i] == '-') {
flag = -1;
++i;
} else if (i < size && str[i] == '+') {
++i;
}
// 转换数字
while (i < size && str[i] >= '0' && str[i] <= '9') {
int digit = str[i] - '0';
// 检查溢出
if (ret > (INT_MAX - digit) / 10) {
return flag == 1 ? INT_MAX : INT_MIN;
}
ret = ret * 10 + digit;
++i;
}
return flag * ret;
}
};
int main() {
Solution sol;
std::string input = " -42";
std::cout << sol.myAtoi(input) << std::endl;
return 0;
}
四、代码逻辑详解
1. 变量初始化
flag
:用于记录结果的正负号,初始值为 1,表示正数。i
:用于遍历字符串的下标,初始值为 0。ret
:用于存储转换后的整数结果,初始值为 0。size
:字符串的长度。
2. 忽略前导空格
while (i < size && str[i] == ' ') {
++i;
}
使用一个 while
循环,从字符串的开头开始,跳过所有的空格字符,直到遇到第一个非空格字符。
3. 处理符号
if (i < size && str[i] == '-') {
flag = -1;
++i;
} else if (i < size && str[i] == '+') {
++i;
}
检查第一个非空格字符是否为 +
或 -
。如果是 -
,则将 flag
设为 -1,表示结果为负数;如果是 +
,则直接跳过该字符;如果没有符号,则默认结果为正数。
4. 转换数字
while (i < size && str[i] >= '0' && str[i] <= '9') {
int digit = str[i] - '0';
// 检查溢出
if (ret > (INT_MAX - digit) / 10) {
return flag == 1 ? INT_MAX : INT_MIN;
}
ret = ret * 10 + digit;
++i;
}
使用一个 while
循环,从符号字符之后开始,依次读取数字字符。将字符转换为对应的数字 digit
,并将其加入到结果 ret
中。在每次更新 ret
之前,检查是否会发生溢出。如果 ret
乘以 10 再加上 digit
会超过 INT_MAX
,则根据 flag
的值返回 INT_MAX
或 INT_MIN
。
5. 返回结果
return flag * ret;
最后,将结果乘以 flag
,得到最终的整数结果并返回。