【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),仅使用了常数级的额外空间。
相关推荐
Dumbness8 分钟前
UIA 读微信群消息没有 id,怎么判断哪条是新的:后缀对齐在翻历史和撤回时整屏重报
python·算法
taka9 分钟前
从 24x 到 141x:我用纯 Python 零依赖项目,扒开了 GPU 加速的性能黑洞
算法
AI的探索之旅12 分钟前
97 个 OpenCV 实例(三十七):二维码识别,一张图四个码的陷阱
c++·opencv·计算机视觉
熊猫钓鱼>_>26 分钟前
鸿蒙 PC 三方库适配复盘:libfvad 1.0 —— 把 WebRTC VAD 做成能装进采集链路的静态库
服务器·开发语言·华为·harmonyos·openharmony·适配·鸿蒙pc
Ai-_Man38 分钟前
Coze扣子还是不可以导出左侧所有对话,只能点进去单条内容导出,方法不对吗?
开发语言·人工智能·ai·小程序·1024程序员节
UIU1141 小时前
P16237 [蓝桥杯 2026 省 B] 应急布线
数据结构·c++·算法·蓝桥杯
raindayinrain1 小时前
c++设计模式
开发语言·c++·设计模式
旖旎夜光1 小时前
LeetCode 315: 算右侧小于当前元素的个数(归并排序) —— 题解
c++·学习·算法·leetcode·排序算法
hiahiahia1231 小时前
Streaming Model Output
开发语言·前端
像风一样自由20201 小时前
2.如何用FastAPI把一个Python算法封装成HTTP服务
python·算法·fastapi