前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【力扣刷题】8. 字符串转换整数 (atoi)

【力扣刷题】8. 字符串转换整数 (atoi)

作者头像
jayjay
发布2022-11-02 16:45:28
5220
发布2022-11-02 16:45:28
举报
文章被收录于专栏:jay_blogjay_blog

一、题目描述

来源:力扣(LeetCode)

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

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

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

本题中的空白字符只包括空格字符 ' ' 。 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

示例 1:

代码语言:javascript
复制
输入:s = "42"
输出:42
解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
第 1 步:"42"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"42"(读入 "42")
           ^
解析得到整数 42 。
由于 "42" 在范围 [-231, 231 - 1] 内,最终结果为 42 。

示例 2:

代码语言:javascript
复制
输入:s = "   -42"
输出:-42
解释:
第 1 步:"   -42"(读入前导空格,但忽视掉)
            ^
第 2 步:"   -42"(读入 '-' 字符,所以结果应该是负数)
             ^
第 3 步:"   -42"(读入 "42")
               ^
解析得到整数 -42 。
由于 "-42" 在范围 [-231, 231 - 1] 内,最终结果为 -42 。

示例 3:

代码语言:javascript
复制
输入:s = "4193 with words"
输出:4193
解释:
第 1 步:"4193 with words"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"4193 with words"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"4193 with words"(读入 "4193";由于下一个字符不是一个数字,所以读入停止)
             ^
解析得到整数 4193 。
由于 "4193" 在范围 [-2^31, 2^31 - 1] 内,最终结果为 4193 。

提示:

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

二、思路分析

代码语言:javascript
复制
本来打算用正则方式的,可是跟题目不符合,速度也慢,题目要求读入每个字符,所以只能迭代字符串,但要要考虑多种情况以及相关处理:
    字符串为空	-->	str.length() == 0
    首尾空格		--->	str.trim()函数 去除首尾空格
    紧接着判定字符串全为空格的情况 --> str.length() == 0
    判断合法首字母是不是数字字符以及加号,减号字符
    判定第一个合法字符是否为 - 号使用标志位记着
    将合法连续数字字符加入到 StringBuild类 s 中
    删除以零开头的连续零字符,注意删除后顺序
    进行字符到数字的处理
    进行数字边界值的处理

三、代码实现

1.正则方式,跟题目不符,不适用,比较简洁

代码语言:javascript
复制
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Solution {
    public int myAtoi(String s) {
        int res = 0;
        Pattern pattern = Pattern.compile("^[+-]?\\d+");
        Matcher matcher = pattern.matcher(s.trim());
        if (matcher.find()) {
            //字符串转整数,溢出
            try {
                res = Integer.parseInt(matcher.group());
            } catch (Exception e){
                //由于有的字符串"42"没有正号,所以我们判断'-'
                res = matcher.group().charAt(0) == '-' ? Integer.MIN_VALUE: Integer.MAX_VALUE;
            }
        }
        return res;
    }
}

2.迭代字符串方式

代码语言:javascript
复制
class Solution {
    public int myAtoi(String s) {
        // 去除空格
        s = s.trim();

        int len = s.length();
        // 空字符串去除
        if(len == 0) return 0;

        int index = 0; // 遍历指针
        int sign = 1; // 默认为正
        // 符号位判断
        if(s.charAt(index) == '-' || s.charAt(index) == '+'){
            sign = s.charAt(index) == '+' ? 1 : -1;
            index ++;
        }
        int res = 0;
        for(; index < len; index++){
            // 字符转数字
            int digit = s.charAt(index) - '0';
            // 遇到非数字
            if(digit < 0 || digit > 9) break;
            // 越界处理
            if(res > Integer.MAX_VALUE/10 || res == Integer.MAX_VALUE/10 &amp;&amp; digit > Integer.MAX_VALUE%10){
                return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            }
            res = res * 10 + digit;
        }
        return sign * res;
    }
}

四、运行结果

image.png
image.png

总结

相对来说,里面要注意的细节还是挺多的,因为字符串的不同,造成的字符合法性和多样性也就更加复杂, 可以想一下,如果是自己来写测试用例i的话,应该要怎么分类,怎么写 关于边界值的处理这一块,需要注意一下,因为以后估计还会用到。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目描述
  • 二、思路分析
  • 三、代码实现
    • 1.正则方式,跟题目不符,不适用,比较简洁
      • 2.迭代字符串方式
      • 四、运行结果
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档