leetcode8字符串转换整数atoi
思路:
空格 | 正负号 | 数字 | 其他 | |
---|---|---|---|---|
start | start | signed | in_number | end |
signed | end | end | in_number | end |
in_number | end | end | in_number | end |
end | end | end | end | end |
上表就是此题的逻辑,左侧是初始状态,右侧是遇到一个字符之后的状态。
有了这个表,思考一会稍加尝试之后发现,手写逻辑过于复杂,所以选择自动机来解决这个题目。
只需要对于字符串中的每个字符都进行一次状态转换,对于in_number状态,进行一次答案更新(需要注意的是,如果爆int,应该更新为INT_MAX或者INT_MIN)对于signed状态进行符号更新,最后返回符号和数值的积即可。
代码:
struct DFA
{
int sign = 1;
long long res = 0;
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_c(char c)
{
if (c == ' ') return 0;
if (c == '+' || c == '-') return 1;
if (c >= '0' && c <= '9') return 2;
return 3;
}
void dfa_get(char c)
{
state = table[state][get_c(c)];
if (state == "in_number")
{
res = res * 10LL + (c - '0');
res = sign == 1 ? min(res, (long long)INT_MAX) : min(res, -(long long)INT_MIN);
}
else if (state == "signed")
{
sign = c == '+' ? 1 : -1;
}
}
};
class Solution {
public:
int myAtoi(string s) {
DFA dfa;
for (char c : s)
dfa.dfa_get(c);
return dfa.sign * dfa.res;
}
};