8. String to Integer (atoi) 【有限状态机】

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%的用户

发布了37 篇原创文章 · 获赞 7 · 访问量 6132
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览