剑指 Offer 67. 把字符串转换成整数

写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。

示例 1:

输入: "42"
输出: 42

示例 2:

输入: "   -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。
     我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

示例 3:

输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。

示例 4:

输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
     因此无法执行有效的转换。

示例 5:

输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。
     因此返回 INT_MIN (−231) 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

使用自动机分析得出:

可以写出状态表

 这个表有一些冗余的数据,编码可以去除

代码如下:

使用HashMap存储状态表,定义一个状态,初始化为start、get_ch方法完成状态的映射,遍历字符串的时候状态可能会发生变化、只到状态变为end,结束循环

解题过程中遇到的难点:

1、状态变化过程中如何捕获结果。

        遍历过程中判断字符是否是数字,是数字的话记录下来。

 2、 使用 StringBuilder 存储结果的话,一旦值超过int类型范围,String 转 int 时 Integer.parseInt()就会报错。

        利用 long 类型来存储结果,遍历是从左到右方向进行的,是数字的话每次遍历乘10加上当前数字,比如123,遍历1,结果为 0 * 10 + 1 = 1 ,结果为1 ,遍历 2 , 1 * 10 + 2 = 12 ,结果为12,遍历3 ,结果为 12 * 10 + 3 = 123,这样结果就出来了。

3、如果字符串的值,超过long类型的极限,怎么办?

          我们知道,方法要求返回 int 类型数据,超过 int 的值对我们是无用的,所以说我们可以在每次得到结果的时候,判断一下是否超过 int 范围,只要超过改为极限值并返回,如果结果没有超过int 就不用管 ,这样结果就不会野蛮生长,把结果没成长之前扼杀在摇篮里。

public int strToInt(String str) {
    HashMap<String, String[]> table = new HashMap<String, String[]>() {
        {
            put("start", new String[]{"start", "sign", "num", "end"});
            put("sign", new String[]{"end", "num"});
            put("num", new String[]{"end", "num"});
            put("end", new String[]{"end"});
        }
    };
    String status = "start";
    int sign = 1;
    long ans = 0;
    for (int i = 0; i < str.length(); i++) {
        char c = str.charAt(i);
        status = table.get(status)[get_ch(c, status)];
        if ("end".equals(status)) {
            break;
        } else if ("start".equals(status)) {
            continue;
        } else if ("sign".equals(status)) {
            if (c == '-') {
                sign = -1;
            }
        } else {
            ans = ans * 10 + Integer.parseInt(c + "");
            ans = sign == 1 ? Math.min(ans, Integer.MAX_VALUE) : Math.max(ans, Integer.MIN_VALUE);
        }

    }
    return ans > (long) Integer.MAX_VALUE ? sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE : sign * (int) ans;
}

public static int get_ch(char ch, String status) {
    if ("start".equals(status)) {

        if (ch == ' ') {
            return 0;
        } else if (ch == '+' || ch == '-') {
            return 1;
        } else if (Character.isDigit(ch)) {
            return 2;
        } else {
            return 3;
        }
    }

    if ("sign".equals(status) || "num".equals(status)) {
        if (Character.isDigit(ch)) {
            return 1;
        } else {
            return 0;
        }
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值