写一个函数 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; }