8. String to Integer (atoi)
题解:
由于数字限制为 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%的用户