Valid Number(验证字符串是否表示数字)

原题链接:http://oj.leetcode.com/problems/valid-number/

Validate if a given string is numeric.

Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true

要求完成如下函数:

class Solution
{
public:
    bool isNumber(const char *s)
    {
    }
}

解决方案:采用有穷自动机可以直观地描述所有可能的数字表达方式。
对于输入的字符串,按照输入在自动机上转换状态,待输入结束时到达可接受状态则为true,否则为false。

1.分析所有的输入可能:

INVALID:%,&,$等无效输入,除过下面几种。
SPACE:空格
SIGN:符号+/-
DIGIT:数字0-9
DOT:点.
EXPONENT:指数符号e|E

2.所有合法输入的可能:

(1):空格 数字 空格,如" 123   "
(2):空格 数字 点 数字 空格,如" 123.4   "
(3):空格 点 数字 空格,如"  .123 "
(4):空格 正负号 数字 空格,如"   +/-123 "
(5):空格 正负号 数字 点 数字 空格,如"  +/-123.4 "
(6):空格 正负号 点 数字 空格,如"  +/-.1234 "
(7):空格 {(1)|(2)|(3)|(4)|(5)|(6)}e|E{(1)|(4)} 空格,如" +/-123.4E123 "," .1234e+/-123 "

如上描述包含了所有的合法输入来表达数字,因此下一步就是用有穷自动机来描述着7种可能。

3.构造有穷自动机,不能有多个节点的环:

state 0:初始状态。

state 1:可接受状态,表示合法输入情况(1)(4)

state 2:接受点

state 3:接受正负号

state 4:接受点或者数字,可接受状态,表示合法输入情况(2)(5)

state 5:接受数字,可接受状态,表示合法输入情况(2)(3)(5)(6)

state 6:接受e|E

state 7:接受正负号

state 8:接受数字,可接受状态,表示合法输入情况(7)

state 9:接受空格,可接受状态,表示合法输入情况(1)(2)(3)(4)(5)(6)(7)

state -1:拒绝状态,表示非法输入

4.写出自动机的状态转换矩阵:

int transitionTable_9[][6]=
        {
        	-1,  0,  3,  1,  2, -1,			//state 0 
        	-1,  9, -1,  1,  4,  6,			//state 1
        	-1, -1, -1,  5, -1, -1,			//state 2
        	-1, -1, -1,  1,  2, -1,			//state 3
        	-1,  9, -1,  5, -1,  6,			//state 4
        	-1,  9, -1,  5, -1,  6,			//state 5
        	-1, -1,  7,  8, -1, -1,			//state 6
        	-1, -1, -1,  8, -1, -1,			//state 7
        	-1,  9, -1,  8, -1, -1,			//state 8
        	-1,  9, -1, -1, -1, -1,			//state 9
        };

每一行表示某一状态,在6种可能的输入下的状态转移。

5.编写代码:

对输入的字符串逐个字符遍历,根据有穷自动机进行状态转移,若输入结束时到达可接受状态则为true,否则为false。如下代码:

class Solution
{
public:
    bool isNumber(const char *s)
    {
        enum InputType
        {
            INVALID,    // 0
            SPACE,      // 1
            SIGN,       // 2
            DIGIT,      // 3
            DOT,        // 4
            EXPONENT,   // 5
            NUM_INPUTS  // 6
        };
        
        int transitionTable_9[][NUM_INPUTS]=
        {
        	-1,  0,  3,  1,  2, -1,			//state 0 
        	-1,  9, -1,  1,  4,  6,			//state 1
        	-1, -1, -1,  5, -1, -1,			//state 2
        	-1, -1, -1,  1,  2, -1,			//state 3
        	-1,  9, -1,  5, -1,  6,			//state 4
        	-1,  9, -1,  5, -1,  6,			//state 5
        	-1, -1,  7,  8, -1, -1,			//state 6
        	-1, -1, -1,  8, -1, -1,			//state 7
        	-1,  9, -1,  8, -1, -1,			//state 8
        	-1,  9, -1, -1, -1, -1,			//state 9
        };
        int state = 0;
        while (*s != '\0')
        {
            InputType inputType = INVALID;
            if (isspace(*s))
                inputType = SPACE;
            else if (*s == '+' || *s == '-')
                inputType = SIGN;
            else if (isdigit(*s))
                inputType = DIGIT;
            else if (*s == '.')
                inputType = DOT;
            else if (*s == 'e' || *s == 'E')
                inputType = EXPONENT;
            
            state = transitionTable_9[state][inputType];
            
            if (state == -1)
                return false;
            else
                ++s;
        }
        
        return state == 1 || state == 4 || state == 5 || state == 8 || state == 9;
    }
};





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值