LeetCode 第 8 题:字符串转换整数 (atoi)
2020/8/14
算法代码
# 题目地址
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/string-to-integer-atoi (opens new window)
# 题目描述
请你来实现一个 atoi 函数,使其能将字符串转换成整数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:
- 如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
- 假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
- 该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
- 注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。
在任何情况下,若函数不能进行有效的转换时,请返回 0 。
提示:
- 本题中的空白字符只包括空格字符 ' ' 。
- 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。
# 个人解题思路
字符串转数字可以使用语言中自带的库来转换,但是题目给的字符串加入了其它东西,所以直接使用自带库的转换函数会报错或者得到错误的结果,不过只需要对字符串进行清理,变成符合要求的并且可以转换的字符串就可以了。
清理的方法:
- 将字符串前面的空格都去除,并且只能清除前面的空格,夹在其它字符中间的空格不能清除
- 对清除空格后的字符串的第一个字符进行判断
- 字符不是正负号和数字,直接返回 0
- 字符是正负号,将正负存为 +1 和 -1 后截取掉,或者直接保留正负号进行转换
- 字符是数字,进行下一步
- 可以分 3 种办法得到可转换的数字字符串
- 将遍历到的数字字符依次存到新的数字字符串,直到遇到非数字符号
- 不断遍历字符,遇到非数字符号后,将后面的字符都截掉得到新的数字字符串
- 直接将数字加到总和,每次操作前需要对总和进行乘以 10 的操作,保证新加的数字在最后一位
- 用内置函数将数字字符串转为数字,判断数字是否超出范围
# 解题代码 Python
class Solution:
def myAtoi(self, str: str) -> int:
# 字符串为空直接返回0
if str == "":
return 0
# 存储进行转换的数字字符串
num_str = "0"
# 字符串截取下标
index = 0
# 遍历字符串字符
while index < len(str):
if str[index] != " ":
# 该字符为正负号
if str[index] == '-' or str[index] == '+':
# 将正负号添加到数字字符串,防止后面没有数字,只有符号导致报错,拼接上字符“0”
num_str = str[index] + "0"
index += 1
elif not (ord('0') <= ord(str[index]) <= ord('9')):
# 该字符串不是正负号也不是数字直接返回0
return 0
# 结束遍历
break
# 字符为空格时继续遍历
index += 1
# 截取掉空格
str = str[index:]
# 遍历新字符串
for char in str:
# 如果是数字将数字添加到数字字符串
if ord('0') <= ord(char) <= ord('9'):
num_str += char
else:
# 如果不是直接结束遍历
break
# 对字符串进行转换后,比较范围后返回结果
# 可能出现的情况:
# 1、有符号,但都后面没有拼接其它数字,但因为拼接符号的时候加上了“0”,所以结果是0
# 2、没符号,也没拼接其它数字,但原本初始值是“0”,所以结果是0
# 3、其它情况是正常情况,返回转换后的数字
return max(min(int(num_str), 2 ** 31 - 1), -2**31)
# 解题代码 Go
func myAtoi(str string) int {
// 存数字的正负
sign := 1
// 依次遍历字符
for index := range str {
// 字符不为空格时,进行字符判断后结束遍历
if str[index] != uint8(' ') {
if str[index] == uint8('-') {
// 如果字符为负号
sign = -1
// 下标向后移一位,截取掉空格和符号
str = str[index+1:]
}else if str[index] == uint8('+'){
// 如果字符为正号
str = str[index+1:]
}else {
// 下标向后移一位,截取掉空格
str = str[index:]
}
break
}
}
// 对新字符串进行遍历
for index := range str {
// 如果该字符不是数字,截取掉后面的字符,保留前面的数字
if str[index] < uint8('0') || str[index] > uint8('9') {
str = str[:index]
break
}
}
// 对字符串进行转换,结果有2种可能
// 1、纯数字,正常转换
// 2、空字符串,返回0和错误信息,错误信息不需要使用到
num, _ := strconv.Atoi(str)
// 比较范围后返回结果
return int(math.Max(math.Min(float64(num*sign), math.Pow(2, 31)-1), math.Pow(-2, 31)))
}