【C++经典例题】字符串转整数(atoi)的实现与解析

【C++经典例题】字符串转整数(atoi)的实现与解析
           💓 博客主页:倔强的石头的ZEEKLOG主页 

           📝Gitee主页:
倔强的石头的gitee主页

            ⏩ 文章专栏:C++经典例题

                                  期待您的关注

 

目录

一、问题描述

二、解题思路

三、代码实现

四、代码逻辑详解

1. 变量初始化

2. 忽略前导空格

3. 处理符号

4. 转换数字

5. 返回结果


 

 

一、问题描述

LCR 192. 把字符串转换成整数 (atoi) - 力扣(LeetCode)

在编程中,经常会遇到将字符串转换为整数的需求,就像标准库中的 atoi 函数一样。

本题要求实现一个 myAtoi 函数,将输入的字符串转换为 32 位有符号整数,具体规则如下:

 

  1. 读入字符串并丢弃无用的前导空格。
  2. 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。确定最终结果是负数还是正数。如果两者都不存在,则假定结果为正。
  3. 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
  4. 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
  5. 如果整数数超过 32 位有符号整数范围 [−2^31, 2^31 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −2^31 的整数应该被固定为 −2^31 ,大于 2^31 − 1 的整数应该被固定为 2^31 − 1 。

二、解题思路

 

为了实现 myAtoi 函数,我们可以按照以下步骤进行:

  1. 忽略前导空格:从字符串的开头开始,跳过所有的空格字符,直到遇到第一个非空格字符。
  2. 处理符号:检查第一个非空格字符是否为 + 或 -,如果是 +,则结果为正数;如果是 -,则结果为负数;如果没有符号,则默认结果为正数。
  3. 转换数字:从符号字符之后开始,依次读取数字字符,将其转换为整数。如果遇到非数字字符,则停止读取。
  4. 溢出处理:在转换数字的过程中,需要检查是否会发生溢出。如果结果超出了 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,得到最终的整数结果并返回。

 

 

 

 

Read more

学 C++ 继承看这篇!派生类函数实现 + 虚继承原理 + IO 库菱形案例,果断收藏

学 C++ 继承看这篇!派生类函数实现 + 虚继承原理 + IO 库菱形案例,果断收藏

✨ 孤廖:个人主页 🎯 个人专栏:《C++:从代码到机器》 🎯 个人专栏:《Linux系统探幽:从入门到内核》 🎯 个人专栏:《算法磨剑:用C++思考的艺术》 折而不挠,中不为下 文章目录 * 正文: * 1. 继承的概念和定义 * 概念: * 定义: * 继承类模板 * 2. 基类和派⽣类间的转换 * 3. 继承中的作⽤域' * 隐藏规则: * 4. 派⽣类的默认成员函数 * 4个常⻅默认成员函数 * 实现一个不能被继承的类 * 5. 继承与友元 * 6. 继承与静态成员 * 7. 多继承及其菱形继承问题 * 继承模型: * 虚继承 * 8. 继承和组合 * 结语: 正文: 1. 继承的概念和定义 概念:

By Ne0inhk
C++之多态

C++之多态

多态 * 什么是多态? * 多态的定义及实现 * 多态的构成条件 * 虚函数 * 虚函数的重写/覆盖 * 关键技术原理 * 最佳实践指南 * 虚函数重写 * 协变 * 析构函数的重写 * override和final关键字 * 纯虚函数和抽象类 * 多态的原理 * 多态是如何实现的 * 1. 虚函数表(vtable) * 虚函数表知识要点 * 2. 虚函数的声明 * 3. 多态的实现过程 * 动态绑定与静态绑定 什么是多态? 多态(Polymorphism)是面向对象编程的三大核心特性之一(封装、继承、多态),源于希腊语"多种形态"。在C++中,它允许我们使用统一的接口处理不同类型的对象,显著提高了代码的灵活性和可扩展性。 核心概念 1. 同一接口,多种形态 不同的对象可以通过相同的方法名调用,但实际执行的逻辑由对象自身的类决定。 2. 解耦调用与实现 调用者只需关注接口(方法名和参数)

By Ne0inhk
纸上谈“型”不如运行识“真”:深入 C++ RTTI 与多态的底层真相!

纸上谈“型”不如运行识“真”:深入 C++ RTTI 与多态的底层真相!

文章目录 * 本篇摘要 * RTTI(Run-Time Type Information,运行时类型信息) 介绍 * RTTI 的核心组成 * 1. `typeid` 运算符 * 2. `dynamic_cast` 运算符 * RTTI 如何工作?(底层原理) * ① 编译器为多态类型做了什么? * ② 当我们调用对应接口,RTTI底层是如何实现呢? * **`场景 1:typeid(obj)`** * 场景 2:dynamic_cast<Derived*> ( p ) * `std::type_info` 类简介 * RTTI 的开销与争议 * 优点: * 缺点: * 何时使用 RTTI? * 禁用 RTTI操作 * 为什么非多态类型不支持 RTTI? * 总结

By Ne0inhk
C++ 波澜壮阔 40 年:从 C with Classes 到现代 C++ 的进化史诗

C++ 波澜壮阔 40 年:从 C with Classes 到现代 C++ 的进化史诗

🔥@晨非辰Tong: 个人主页 👀专栏:《数据结构与算法入门指南》、《C++学习之旅》 💪学习阶段:C语言、数据结构与算法初学者 ⏳“人理解迭代,神理解递归。” 文章目录 * 引言 * 一、波澜壮阔的C++“发家”历史 * 1. 1 C with Classes (1979-1983)-起源 * 1.2 早期发展:C++的"++"从何来(1983-1989) * 1.3 标准化与成熟(1990-1998) * 1.4 现代化浪潮(2011-至今) * 二、推荐C++学习参考网站、好用书籍 * 三、梦开始的地方:C++的第一个程序 * 3.

By Ne0inhk