您的位置:首页 > 教育 > 锐评 > LeetCode - 8 字符串转换整数 (atoi)

LeetCode - 8 字符串转换整数 (atoi)

2024/10/6 10:42:38 来源:https://blog.csdn.net/qfc_128220/article/details/141715464  浏览:    关键词:LeetCode - 8 字符串转换整数 (atoi)

题目来源

8. 字符串转换整数 (atoi) - 力扣(LeetCode)

 

题目描述

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

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

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

返回整数作为最终结果。

示例 1

输入:s = "42"

输出:42

解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。

带下划线线的字符是所读的内容,插入符号是当前读入位置。
第 1 步:"42"(当前没有读入字符,因为没有前导空格)
                ^
第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
                ^
第 3 步:"42"(读入 "42")
                    ^

示例 2

输入:s = " -042"

输出:-42

解释:

第 1 步:"   -042"(读入前导空格,但忽视掉)
                   ^
第 2 步:"   -042"(读入 '-' 字符,所以结果应该是负数)
                     ^
第 3 步:"   -042"(读入 "042",在结果中忽略前导零)
                         ^

示例 3

输入:s = "1337c0d3"

输出:1337

解释:

第 1 步:"1337c0d3"(当前没有读入字符,因为没有前导空格)
                ^
第 2 步:"1337c0d3"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
                ^
第 3 步:"1337c0d3"(读入 "1337";由于下一个字符不是一个数字,所以读入停止)
                        ^

示例 4

输入:s = "0-1"

输出:0

解释:

第 1 步:"0-1" (当前没有读入字符,因为没有前导空格)
                ^
第 2 步:"0-1" (当前没有读入字符,因为这里不存在 '-' 或者 '+')
                ^
第 3 步:"0-1" (读入 "0";由于下一个字符不是一个数字,所以读入停止)
                  ^

示例 5

输入:s = "words and 987"

输出:0

解释:

读取在第一个非数字字符“w”处停止。

提示

  • 0 <= s.length <= 200
  • s 由英文字母(大写和小写)、数字(0-9)、' '、'+'、'-' 和 '.' 组成

题目解析

本题可以分为两部分逻辑:

  1. 读入最终结果数字串
  2. 判断最终结果数字串是否超出 int 范围

读入最终结果数字串逻辑如下:

  1. 首先,跳过前导空格
  2. 接着,读入最终结果的符号部分 sign,可能没有符号,此时默认为正数
  3. 最后,读入最终结果的数字部分 num,可能含有前导0,但是不影响结果

判断一个数字串是否超出 int 范围,我们可以从高位到低位,依次读取该数字串的每个字符 c,将计算结果记录进 res 中,res初始为0:

res = res * 10 + (c - '0')

按上面公式,先计算进res的高位数字后续会不断 *10,抬高位序。

如果计算过程中,发现 res 超出了 int 范围(一步一步计算的过程,绝对不会超出 long 范围,因此 res 可以定义为 long 类型),则停止计算,返回对应 int 边界值。

更多细节逻辑,请看代码实现。

C源码实现

int myAtoi(char* s) {int i = 0;while (i < strlen(s) && s[i] == ' ') { // 跳过无用的前导空格i++;}int sign = 1; // sign录入最终结果的符号部分, 1表示正, -1表示负, 默认为正if (i < strlen(s) && (s[i] == '+' || s[i] == '-')) { // 如果有开头+或-号, 则更新sign信息sign = s[i] == '-' ? -1 : 1;i++;}char num[201] = {'\0'};  // num录入最终结果的数字部分int num_size = 0;for (; i < strlen(s); i++) {if (s[i] >= '0' && s[i] <= '9') {num[num_size++] = s[i];} else {break;}}// 判断一个数值是否超过int范围long res = 0;for (int j = 0; j < num_size; j++) {res = res * 10 + (num[j] - '0');if (res * sign >= INT_MAX) {return INT_MAX;}if (res * sign <= INT_MIN) {return INT_MIN;}}return (int)res * sign;
}

C++源码实现

class Solution {
public:int myAtoi(string s) {int i = 0;while (i < s.length() && s[i] == ' ') { // 跳过无用的前导空格i++;}int sign = 1; // sign录入最终结果的符号部分, 1表示正, -1表示负, 默认为正if (i < s.length() &&(s[i] == '+' || s[i] == '-')) { // 如果有开头+或-号, 则更新sign信息sign = s[i] == '-' ? -1 : 1;i++;}string num; // num录入最终结果的数字部分for (; i < s.length(); i++) {if (s[i] >= '0' && s[i] <= '9') {num += s[i];} else {break;}}// 判断一个数值是否超过int范围long res = 0;for (int j = 0; j < num.length(); j++) {res = res * 10 + (num[j] - '0');if (res * sign >= INT_MAX) {return INT_MAX;}if (res * sign <= INT_MIN) {return INT_MIN;}}return (int) res * sign;}
};

 

Java源码实现

class Solution {public int myAtoi(String s) {int i = 0;while (i < s.length() && s.charAt(i) == ' ') { // 跳过无用的前导空格i++;}int sign = 1; // sign录入最终结果的符号部分, 1表示正, -1表示负, 默认为正if (i < s.length() && (s.charAt(i) == '+' || s.charAt(i) == '-')) { // 如果有开头+或-号, 则更新sign信息sign = s.charAt(i) == '-' ? -1 : 1;i++; // 跳过符号}StringBuilder num = new StringBuilder(); // num录入最终结果的数字部分for (; i < s.length(); i++) {char c = s.charAt(i);if (c >= '0' && c <= '9') {num.append(c);} else {break;}}// 判断一个数值是否超过int范围long res = 0;for (int j = 0; j < num.length(); j++) {res = res * 10 + (num.charAt(j) - '0');if (res * sign >= Integer.MAX_VALUE) {return Integer.MAX_VALUE;}if (res * sign <= Integer.MIN_VALUE) {return Integer.MIN_VALUE;}}return (int) res * sign;}
}

 

Python源码实现

class Solution(object):def myAtoi(self, s):""":type s: str:rtype: int"""i = 0while i < len(s) and s[i] == ' ':  # 跳过无用的前导空格i += 1sign = 1  # sign录入最终结果的符号部分, 1表示正, -1表示负, 默认为正if i < len(s) and (s[i] == '+' or s[i] == '-'):  # 如果有开头+或-号, 则更新sign信息sign = -1 if s[i] == '-' else 1i += 1num = ""  # num录入最终结果的数字部分while i < len(s):if '9' >= s[i] >= '0':num += s[i]else:breaki += 1INT_MAX = pow(2, 31) - 1INT_MIN = -pow(2, 31)# 判断一个数值是否超过int范围res = 0for j in range(len(num)):res = res * 10 + int(num[j])if res * sign >= INT_MAX:return INT_MAXif res * sign <= INT_MIN:return INT_MINreturn res * sign

JavaScript源码实现

/*** @param {string} s* @return {number}*/
var myAtoi = function (s) {let i = 0;while (i < s.length && s[i] == " ") {// 跳过无用的前导空格i++;}let sign = 1; // sign录入最终结果的符号部分, 1表示正, -1表示负, 默认为正if (i < s.length && (s[i] == "+" || s[i] == "-")) {// 如果有开头+或-号, 则更新sign信息sign = s[i] == "-" ? -1 : 1;i++;}let num = ""; // num录入最终结果的数字部分for (; i < s.length; i++) {if (s[i] >= "0" && s[i] <= "9") {num += s[i];} else {break;}}const INT_MAX = Math.pow(2, 31) - 1;const INT_MIN = -Math.pow(2, 31);// 判断一个数值是否超过int范围let res = 0;for (let j = 0; j < num.length; j++) {res = res * 10 + parseInt(num[j]);if (res * sign >= INT_MAX) {return INT_MAX;}if (res * sign <= INT_MIN) {return INT_MIN;}}return res * sign;
};

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com