题目
验证给定的字符串是否可以解释为十进制数字。
例如:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
" -90e3 " => true
" 1e" => false
"e3" => false
" 6e-1" => true
" 99e2.5 " => false
"53.5e93" => true
" --6 " => false
"-+3" => false
"95a54e53" => false
说明: 我们有意将问题陈述地比较模糊。在实现代码之前,你应当事先思考所有可能的情况。这里给出一份可能存在于有效十进制数字中的字符列表:
- 数字 0-9
- 指数 - “e”
- 正/负号 - “+”/"-"
- 小数点 - “.”
当然,在输入中,这些字符的上下文也很重要。
思路
采用《编译原理》里面的确定的有限状态机(DFA)解决。
- 状态机的要素
状态机可归纳为4个要素,即现态、条件、动作、次态。“现态”和“条件”是因,“动作”和“次态”是果。详解如下:- 现态:是指当前所处的状态。
- 条件:又称为“事件”。当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。
- 动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。
- 次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。
- 确定的有限自动状态机(DFA)特点:
- 在DFA中,给定当前状态,我们能够知道下一个状态。
- 下一个状态是唯一确定的。
- 从符号空间中选择任意一个符号输入,总有一个唯一确定的下一状态。比如上图中,符号空间为{0,1},当前状态为A,输入1,那么下一个状态百分之百是B,输入0,为C,其它状态亦然。
- 简单且容易实现。
根据《编译原理》的解释,DFA 从状态 0 接受串 s 作为输入。当s耗尽的时候如果当前状态处于中间状态,则拒绝;如果到达终止状态,则接受。
状态机对应到本题可以这样理解:
例如当我们读到 0-9
时,我们就处于某个状态,这个状态允许的下一个合法的字符我们是能确定的,例如 0-9
后面可以有 '0'-'9', '.', 'e', ' ', ...
,当然具体还要结合上下文,当下一个字符是合法的,那么就可以进入一个新的状态,当下一个字符不合法时,则无法进入下一个状态,这个时候状态机无法继续向下进行,那么就可以简单理解为 “编译出错” ;
那么本题可以画出状态图:
图中红色为 终止状态,蓝色为 中间状态;
有了状态图,就可以写出状态转移表:
状态 | 条件 blank | 条件 +/- | 条件 0-9 | 条件 . | 条件 e | other |
---|---|---|---|---|---|---|
0 | 0 | 1 | 6 | 2 | -1 | -1 |
1 | -1 | -1 | 6 | 2 | -1 | -1 |
2 | -1 | -1 | 3 | -1 | -1 | -1 |
3 | 8 | -1 | 3 | -1 | 4 | -1 |
4 | -1 | 7 | 5 | -1 | -1 | -1 |
5 | 8 | -1 | 5 | -1 | -1 | -1 |
6 | 8 | -1 | 6 | 3 | 4 | -1 |
7 | -1 | -1 | 5 | -1 | -1 | -1 |
8 | 8 | -1 | -1 | -1 | -1 | -1 |
其实上