#import "../../../../lib.typ":*

=== #Title(
  title: [字符串转换整数],
  reflink: "https://leetcode.cn/problems/string-to-integer-atoi/description/",
  level: 2,
)<字符串转换整数>

#note(
  title: [
字符串转换整数
  ],

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

函数 myAtoi(string s) 的算法如下：

空格：读入字符串并丢弃无用的前导空格（" "）
符号：检查下一个字符（假设还未到字符末尾）为 '-' 还是 '+'。如果两者都不存在，则假定结果为正。
转换：通过跳过前置零来读取该整数，直到遇到非数字字符或到达字符串的结尾。如果没有读取数字，则结果为0。
舍入：如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ，需要截断这个整数，使其保持在这个范围内。具体来说，小于 −231 的整数应该被舍入为 −231 ，大于 231 − 1 的整数应该被舍入为 231 − 1 。
返回整数作为最终结果。
  ],

  examples: ([
输入：s = "42"

输出：42

解释：
```typc
带下划线线的字符是所读的内容，插入符号是当前读入位置。
第 1 步："42"（当前没有读入字符，因为没有前导空格）
         ^
第 2 步："42"（当前没有读入字符，因为这里不存在 '-' 或者 '+'）
         ^
第 3 步："42"（读入 "42"）
           ^
```               
    ],[
输入：s = " -042"

输出：-42

解释：
```typc
第 1 步："   -042"（读入前导空格，但忽视掉）
            ^
第 2 步："   -042"（读入 '-' 字符，所以结果应该是负数）
             ^
第 3 步："   -042"（读入 "042"，在结果中忽略前导零）
               ^
```
    ],[
输入：s = "1337c0d3"

输出：1337

解释：
```typc
第 1 步："1337c0d3"（当前没有读入字符，因为没有前导空格）
         ^
第 2 步："1337c0d3"（当前没有读入字符，因为这里不存在 '-' 或者 '+'）
         ^
第 3 步："1337c0d3"（读入 "1337"；由于下一个字符不是一个数字，所以读入停止）
             ^
```             
    ],[
输入：s = "0-1"

输出：0

解释：
```typc
第 1 步："0-1" (当前没有读入字符，因为没有前导空格)
         ^
第 2 步："0-1" (当前没有读入字符，因为这里不存在 '-' 或者 '+')
         ^
第 3 步："0-1" (读入 "0"；由于下一个字符不是一个数字，所以读入停止)
          ^
```                
    ],[
输入：s = "words and 987"

输出：0

解释：
```typc
读取在第一个非数字字符“w”处停止。
```      
    ]
  ),

  tips: [
- $0 <= s."length" <= 200$
- s 由英文字母（大写和小写）、数字（0-9）、' '、'+'、'-' 和 '.' 组成
  ],

  solutions: (
  ( name:[字符串解析],
    text:[
根据题意，有以下四种字符需要考虑：

+ 首部空格： 删除之即可。
+ 符号位： 三种情况，即 ''+'' , ''−'' , ''无符号" ；新建一个变量保存符号位，返回前判断正负即可。
+ 非数字字符： 遇到首个非数字的字符时，应立即返回。
+ 数字字符：
  + 字符转数字： “此数字的 ASCII 码” 与 “ 0 的 ASCII 码” 相减即可。
  + 数字拼接： 若从左向右遍历数字，设当前位字符为 c ，当前位数字为 x ，数字结果为 res ，则数字拼接公式为：$"res"=10 × "res"+x; 

x="ascii"(c)− "ascii"( ′0 ′ )$

*数字越界处理：*

题目要求返回的数值范围应在 $[−2^31,2^31−1]$ ，因此需要考虑数字越界问题。而由于题目指出 环境只能存储 32 位大小的有符号整数 ，因此判断数字越界时，要始终保持 res 在 int 类型的取值范围内。
  ],code:[
```cpp
class Solution {
public:
    int myAtoi(string s) {
        int i = 0;
        int n = s.size();
        // 去除前导空格
        while (i < n && s[i] == ' ') {
            i++;
        }
        // 判断是否为空字符串
        if (i == n) {
            return 0;
        }
        int flag = 1;
        if (s[i] == '-') {
            flag = -1;
            i++;
        } else if (s[i] == '+') {
            i++;
        }
        int ans = 0;
        // 读取数字
        while (i < n) {
            if (s[i] < '0' || s[i] > '9') {// 遇到非数字字符则退出
                break;
            }
            int digit = s[i] - '0';
            if (ans > (INT_MAX - digit) / 10) {// 判断是否溢出
                return flag == 1 ? INT_MAX : INT_MIN;
            }
            ans = ans * 10 + digit;
            i++;
        }
        return flag * ans;

    }
};
```      
  ]),

  ),

  gain:none,
)
