题解:
由于数字限制为 int 32位,为了简化算法采用 long int 64位进行处理,算法采用编译原理中有限状态机的方案,初始状态为0。
0 状态:遇到空格字符时,状态不发生变化,仍为0;
遇到字母字符/非数字字符/非负号时,变为无效状态 4;
遇到数字字符时,变为无符号读取状态 1,并标记 Flag 为正数读取;
遇到负号字符/正号字符时,变为有符号读取状态 2,并标记Flag为负号/正号读取;
1 状态:遇到空格符/字母/负号/任何非数字字符时,表明读数结束,变为结束状态 3;
遇到数字字符时,表明读数继续,仍为状态 1;
2 状态:遇到空格符/字母/负号/任何非数字字符时,表明读数错误,变为无效状态 4;
遇到数字字符时,表明开始读负数/正数,变为读取状态 1;
3 状态:终止状态,停止变换并返回有效数据;
4 状态:无效状态,停止变换并返回无效数据 0;
针对每个状态的具体处理方法和算法实现细节请参考源码:
class Solution {
public:
int myAtoi(string str) {
int len = str.size();
char ch;
int state = 0; // 状态初始为0;
int signFlag; // 数字符号状态;
long int res = 0;
for(int i = 0; i < len; ){
ch = str[i];
if(state == 0){
if(ch == ' '){
state = 0;
i++;
}
else if(isDigit(ch)){
signFlag = 1; // 正数读取
state = 1;
}
else if(ch == '+' || ch == '-'){
signFlag = ch == '+';
state = 2;
i++;
}
else{
state = 4;
}
}
else if(state == 1){
if(!isDigit(ch)){
state = 3;
}
else{
state = 1;
res = res * 10 + ch - '0';
if(signFlag){
if(res > 0x7fffffff){ //正数上限判断
res = 0x7fffffff;
state = 3;
}
}
else{
if(res > 0x80000000){ //负数下限判断
res = 0x80000000;
signFlag = 1; //由于res被置为最大负数,因此在后面intres不能再取负
state = 3;
}
}
i++;
}
}
else if(state == 2){
if(!isDigit(ch)){
state = 4;
}
else{
state = 1;
}
}
else if(state == 3){
break;
}
else if(state == 4){
res = 0;
break;
}
}
int intres = res;
if(!signFlag){
intres = -res;
}
return intres;
}
private:
bool isDigit(char ch){
return (ch >= '0' && ch <= '9');
}
};
结果展示:
执行结果:
通过
显示详情
执行用时 :0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗 :8.5 MB, 在所有 C++ 提交中击败了78.27%的用户