字符串转换整数 (atoi)[leetcode 8]笔记
要求:
- 读入字符串并丢弃无用的前导空格
- 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
- 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
- 将前面步骤读入的这些数字转换为整数(即,“123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
-如果整数数超过 32 位有符号整数范围 [ − 2 31 −2^{31} −231, 2 31 − 1 2^{31} − 1 231−1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 − 2 31 −2^{31} −231 的整数应该被固定为 − 2 31 −2^{31} −231 ,大于 2 31 − 1 2^{31}-1 231−1的整数应该被固定为 2 31 − 1 2^{31}-1 231−1 。
返回整数作为最终结果。 - 空白字符只包括空格字符 ’ ’
- s 由英文字母(大写和小写)、数字(0-9)、’ ‘、’+’、’-’ 和 ‘.’ 组成
输入输出:
输入:"2456"
输出:2456
-------------
输入:"yyyy256"
输出:0
-------------
输入:" 5689 eee"
输出:5689
方法一:
跟着题目要求一步一步走。
- 先去掉字符两边的空格。
- 判断符号。
- 读取数字。
class Solution {
public int myAtoi(String s) {
s = s.trim(); //去除字符串两边的空格
if(s.length()==0) return 0; //如果此时字符串长度为0,则返回0
int length = s.length(); //记录当前字符串长度
int index = 0; // 记录字符串中字符下标
int ans = 0; // 记录最终的数值,不带正负号
int sign = 1; // 记录正负号,1是正数,-1是负数,默认为正数
if(s.charAt(index)=='+'||s.charAt(index)=='-') // 判断正负号
sign = s.charAt(index++)=='+'?1:-1;
for(;index<length;index++){ //遍历字符串中的字符
//取出字符串中字符,然后转化为数字
int digit = s.charAt(index) - '0';
//读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。
//字符串的其余部分将被忽略。如果读取了非数字,后面的都要忽略
if(digit<0||digit>9) break;
if(ans>Integer.MAX_VALUE /10 || (ans == Integer.MAX_VALUE /10 && digit>Integer.MAX_VALUE%10))
return sign==1?Integer.MAX_VALUE:Integer.MIN_VALUE;
else
ans = ans * 10 + digit;
}
return ans*sign;
}
}
方法二:
- 对于有许多状态转换的算法过程,可以使用有限自动机来表示算法过程,是程序逻辑更加清晰。
- 我们的程序在每个时刻有一个状态 s,每次从序列中输入一个字符 c,并根据字符 c 转移到下一个状态 s’。这样,我们只需要建立一个覆盖所有情况的从 s 与 c 映射到 s’ 的表格即可解决题目中的问题。
我们也可以用下面的表格来表示这个自动机:
class Solution {
public int myAtoi(String str) {
Automaton automaton = new Automaton();
int length = str.length();
for (int i = 0; i < length; ++i) {
automaton.get(str.charAt(i));
}
return (int) (automaton.sign * automaton.ans);
}
}
class Automaton {
public int sign = 1;
public long ans = 0;
private String state = "start";
private Map<String, String[]> table = new HashMap<String, String[]>() {{
put("start", new String[]{"start", "signed", "in_number", "end"});
put("signed", new String[]{"end", "end", "in_number", "end"});
put("in_number", new String[]{"end", "end", "in_number", "end"});
put("end", new String[]{"end", "end", "end", "end"});
}};
public void get(char c) {
state = table.get(state)[get_col(c)];
if ("in_number".equals(state)) {
ans = ans * 10 + c - '0';
ans = sign == 1 ? Math.min(ans, (long) Integer.MAX_VALUE) : Math.min(ans, -(long) Integer.MIN_VALUE);
} else if ("signed".equals(state)) {
sign = c == '+' ? 1 : -1;
}
}
private int get_col(char c) {
if (c == ' ') {
return 0;
}
if (c == '+' || c == '-') {
return 1;
}
if (Character.isDigit(c)) {
return 2;
}
return 3;
}
}
参考链接: