【C++算法打怪专栏】8. 字符串转换整数 (atoi)

【C++算法打怪专栏】8. 字符串转换整数 (atoi)

1. 题目描述

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数。

处理规则:

  1. 前导空格: 读入字符串并丢弃无用的前导空格 ' '。
  2. 正负号: 检查下一个字符为 '-' 还是 '+'(若都不存在,默认为正)。
  3. 转换数字: 跳过前置零并读取连续数字,直到遇到非数字字符或到达字符串结尾。
  4. 范围截断: 若结果超过 32 位有符号整数范围 INT_MIN,INT_MAXINT\\_MIN, INT\\_MAXINT_MIN,INT_MAX(即 −231,231−1-2\^{31}, 2\^{31} - 1−231,231−1),则截断返回对应的边界值。

2. 核心避坑点分析

编写该题时,容易出现以下几类逻辑错误:

  • 条件判断错误: s[i] != '-' || s[i] != '+' 属于逻辑恒真条件(字符不可能同时是两个不同符号),会导致分支控制失效。
  • 数字字符比较误区: s[i] >= 0 && s[i] <= 9 比较的是 ASCII 码 0~9 的控制字符,正确写法应为 '0' <= s[i] && s[i] <= '9' 或使用 std::isdigit()。
  • 索引越界与跳过: 若初始指针直接从 1 开始,当首字符就是合法数字时会导致漏读第一个数字。
  • 数据溢出问题: 未提前判断累加过程中的数值溢出,可能导致 int 越界产生未定义行为。

3. 解题思路与步骤

采用单指针扫描法,按顺序完成以下三步:

  1. 清除前置空格: 使用指针 i 跳过开头的连续空格。
  2. 提取符号: 检查当前字符是否为正负号,用变量 sign(1 或 -1)标记正负,同时指针自增。
  3. 按位累加并检查溢出:
    • 逐位读取数字字符并计算 res = res * 10 + (s[i] - '0')。
    • 溢出处理: 在每一步计算后(或累加前)检查 sign * res 是否超出 INT_MAX / INT_MIN 范围,若超出则立即返回边界值。

4. C++ 代码实现

cpp 复制代码
#include <string>
#include <climits>

class Solution {
public:
    int myAtoi(std::string s) {
        int i = 0;
        int n = s.size();

        // 1. 忽略前导空格
        while (i < n && s[i] == ' ') {
            i++;
        }

        // 2. 处理正负号
        int sign = 1;
        if (i < n && (s[i] == '+' || s[i] == '-')) {
            sign = (s[i] == '-') ? -1 : 1;
            i++;
        }

        // 3. 转换数字并实时判断溢出
        long long res = 0; // 使用 long long 防止累加过程中 int 直接溢出
        while (i < n && s[i] >= '0' && s[i] <= '9') {
            int digit = s[i] - '0';
            res = res * 10 + digit;

            // 检查 32 位有符号整数边界
            if (sign * res >= INT_MAX) return INT_MAX;
            if (sign * res <= INT_MIN) return INT_MIN;

            i++;
        }

        return static_cast<int>(sign * res);
    }
};

5. 复杂度分析

  • 时间复杂度: O(N)O(N)O(N),其中 NNN 是字符串 s 的长度,只需对字符串进行一次单向遍历。
  • 空间复杂度: O(1)O(1)O(1),仅使用了常数级的额外空间。
相关推荐
爱吃香菜的初学者1 小时前
十四.Linux——消息队列
linux·运维·开发语言
迅猛龙办公室1 小时前
python实现倒序输出数字
开发语言·python
h39746 小时前
DirectShow过滤器开发-视频源过滤器
c++·windows·音视频·directshow
夏幻灵7 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
程序猿编码7 小时前
榨干 RTX5090 算力!Qwen3 专用单卡推理引擎,手写C++/CUDA 算子实现 MTP 推测解码
开发语言·c++·大模型推理·qwen3·多模态推理
西飘客8 小时前
vs 怎么根据dll 生成lib文件
c++·qt
bkspiderx9 小时前
Qt 插件机制:动态扩展应用功能的核心框架
开发语言·qt·元数据·qt 插件·qpluginloader
程序员老陆9 小时前
深入理解 C++ thread_local:线程私有存储的正确打开方式
开发语言·c++·程序设计
沐晓时光9 小时前
C语言入门,深入理解指针(3)
c语言·开发语言