《剑指offer》-表示数值的字符串

本文介绍了一个用于判断字符串是否表示数值的方法。通过构建有限状态机(DFA),实现了对字符串的有效识别,能够准确判断字符串是否符合整数、小数及科学计数法的格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。

题目是要判断一个表达式是否满足预设规则。其实就是正则匹配。正则匹配的原理,编译原理课上有讲过,用NFA/DFA来判定即可。

648934_1462774918833_F749A40EE1DEB00F52A


class Solution {
private:
    enum STATUS{ END = 0, START, SIGNED1, INTEGER, POINT, FLOAT, EXPONENT, SIGNED2, SCIENCE };
    STATUS dfa[256][9] = { END };
public:
    Solution(){
        for (int i = 0; i < 256; ++i){
            for (int j = 0; j < 9; ++j){
                dfa[i][j] = END;
            }
        }
        initDFA();
    }
    bool isNumeric(char* string){
        STATUS current = START;
        while (*string && current != END){
            current = DFA(current, *string);
            ++string;
        }
        switch (current){
        case INTEGER:
        case FLOAT:
        case SCIENCE:
            return true;
        }
        return false;
    }
private:
    void initDFA(){
        char d = '0';
        // 1. START 变迁
        dfa['+'][START] = SIGNED1;
        dfa['-'][START] = SIGNED1;
        dfa['.'][START] = POINT;
        for (d = '0'; d <= '9'; ++d){
            dfa[d][START] = INTEGER;
        }

        // 2. SIGNED1 变迁
        for (d = '0'; d <= '9'; ++d){
            dfa[d][SIGNED1] = INTEGER;
        }
        dfa['.'][SIGNED1] = POINT;

        // 3. INTEGER 变迁
        for (d = '0'; d <= '9'; ++d){
            dfa[d][INTEGER] = INTEGER;
        }
        dfa['.'][INTEGER] = FLOAT;
        dfa['E'][INTEGER] = EXPONENT;
        dfa['e'][INTEGER] = EXPONENT;

        // 4. POINT 变迁
        for (d = '0'; d <= '9'; ++d){
            dfa[d][POINT] = FLOAT;
        }

        // 5. FLOAT 变迁
        for (d = '0'; d <= '9'; ++d){
            dfa[d][FLOAT] = FLOAT;
        }
        dfa['E'][FLOAT] = EXPONENT;
        dfa['e'][FLOAT] = EXPONENT;

        // 6. EXPONENT 变迁
        for (d = '0'; d <= '9'; ++d){
            dfa[d][EXPONENT] = SCIENCE;
        }
        dfa['+'][EXPONENT] = SIGNED2;
        dfa['-'][EXPONENT] = SIGNED2;

        // 7. SIGNED2 变迁
        for (d = '0'; d <= '9'; ++d){
            dfa[d][SIGNED2] = SCIENCE;
        }

        // 8. SCIENCE 变迁
        for (d = '0'; d <= '9'; ++d){
            dfa[d][SCIENCE] = SCIENCE;
        }

        // 其余情况均变迁到 END
    }

    STATUS DFA(STATUS current, char input){
        STATUS ret = START;
        return dfa[input][current];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值