8. 字符串转换整数 (atoi)

class Solution(object):
    def myAtoi(self, s):
        """
        :type s: str
        :rtype: int
        """
        s = s.strip()
        if len(s) == 0:
            return 0

        convert = 1
        tmp_str = ""
        tmp_str_len = 0
        answer = 0
        limit = pow(2, 31)
        num_idx = -1
        symbol_idx = len(s) + 1

        # print(s)
        if s[0] == '+' or s[0] == '-':
            symbol_idx = 0
            if s[0] == '+':
                convert = 1
            elif s[0] == '-':
                convert = -1

        # print(symbol_idx)
        for i in range(len(s)):
            # print(value,s.index(value))
            if s[i].isdigit():
                tmp_str += s[i]
            else:
                if i == symbol_idx:
                    continue
                else:
                    break

        # print(tmp_str)
        if tmp_str == "" :
            return 0

        tmp_str_len = len(tmp_str)
        for i in range(tmp_str_len):
            answer += int(tmp_str[i]) * pow(10, (tmp_str_len - i - 1))

        answer *= convert

        if answer < -1 * limit:
            answer = -1 * limit
        elif answer > limit - 1:
            answer = limit - 1

        return answer


if __name__ == '__main__':
    ret = Solution()
    para = "21474836460"
    print(ret.myAtoi(para))

首先是输入字符串的前导空格的取出,我这边直接调用了库函数:

s = s.strip()

这样转换之后就是不带前导空格的字符串了。

接下来要判断正负了,刚开始我理解错题目了,我以为是正负号在字符串中间出现的话一样当作数字符号处理,仔细看题目之后才发现只需要处理字符串开头的正负号即可,这就简单了:

if s[0] == '+' or s[0] == '-':
   symbol_idx = 0
   if s[0] == '+':
       convert = 1
   elif s[0] == '-':
       convert = -1

我设置了一个符号变量,在最后的return之前将输出乘以该变量即可。

接下来就是整个逻辑的主题部分了,那就是提取出字符串里的连续数字字符串:

我用到了python自带的基础库函数isdigit(),可以判断字符是否为数字,整体逻辑如下所示:

for i in range(len(s)):
    # print(value,s.index(value))
    if s[i].isdigit():
        tmp_str += s[i]
    else:
        if i == symbol_idx:
            continue
        else:
            break
if tmp_str == "" :
    return 0

这里我用了一个小技巧,那就是我会先找正负号的位置,找到之后将其赋值给symbol_idx,接下来重新进行遍历,当遇到symbol_idx之后就跳过不做判断,以防程序过早中断。

当第二次遍历之后我再判断tmp_str是否为空,如果为空说明数字字符串没有在字母之前,那就直接返回0即可,否则就将tmp_str转换成数字:

tmp_str_len = len(tmp_str)
for i in range(tmp_str_len):
    answer += int(tmp_str[i]) * pow(10, (tmp_str_len - i - 1))

answer *= convert

在题目中还对输出进行了限幅:

limit = pow(2, 31)
if answer < -1 * limit:
     answer = -1 * limit
 elif answer > limit - 1:
     answer = limit - 1