首先解释一下题目中的atoi,它其实是C语言中的库函数,主要的作用是将字符串转换为int整数,与此相类似的还有
atol:把字符串nptr转换为long int。
atol:把字符串nptr转换为long long int。
atoq:atoq() is an obsolete name for atoll()。
接下来我们来分析题目。
方法一:根据题目的描述,可以想到模拟来解决这道题,跟据题目的提供的思想,一步一步的模拟,同时还应该考虑到模拟时的边界问题。代码如下所示
class Solution {
public:
int myAtoi(string s) {
int idx = 0;
int n = s.size()
if(s[idx] == ' ' && idx < n){ //判断前导空格
idx++;
}
if(idx == n){
return 0; //如果只有空格,则返回0
}
bool negative = true;
if(s[idx] == '+'){ // 判断正负
idx++;
}
else if(s[idx] == '-'){
negative = false;
idx++;
}
int ans = 0;
while(idx < n && s[idx] >= '0' && s[idx] <= '9'){//如果字符在‘0’到‘9’之间则继续循环
int digit = s[idx] - '0';
if(ans > (INT_MAX - digit) / 10){//判断是否越界
return negative ? INT_MAX : INT_MIN;
}
ans = ans * 10 +digit;
idx++;
}
return negative ? ans : -ans;
}
};
方法二:该题还有一种叫自动机的解法,就是利用确定的有穷自动机(简称DFA)。该方法主要涉及到的知识点是编译原理中的不确定有穷自动机,再利用数据结构的思想来实现的,具体较上个方法复杂,未学习过编译原理的可以自行选择学习。
class Automaton {
string state = "start";
unordered_map<string, vector<string>> table = {
{"start", {"start", "signed", "in_number", "end"}},
{"signed", {"end", "end", "in_number", "end"}},
{"in_number", {"end", "end", "in_number", "end"}},
{"end", {"end", "end", "end", "end"}}
};
int get_col(char c) {
if (isspace(c)) return 0;
if (c == '+' or c == '-') return 1;
if (isdigit(c)) return 2;
return 3;
}
public:
int sign = 1;
long long ans = 0;
void get(char c) {
state = table[state][get_col(c)];
if (state == "in_number") {
ans = ans * 10 + c - '0';
ans = sign == 1 ? min(ans, (long long)INT_MAX) : min(ans, -(long long)INT_MIN);
}
else if (state == "signed")
sign = c == '+' ? 1 : -1;
}
};
class Solution {
public:
int myAtoi(string str) {
Automaton automaton;
for (char c : str)
automaton.get(c);
return automaton.sign * automaton.ans;
}
};