题目链接
这道题首先要明确requirement,举足够多的例子确定cover所有的edge cases,比如:
- 普通的整数和小数都是valid的,比如9和0.3
- 9. 和 .3也都是valid的,但是只有一个.肯定不是valid的
- 科学计数法的情况下,前半部分允许出现整数或者小数,后半部分只允许整数
- 9e3, -5.4e-6都是valid的
- 5e3.4不是valid的
- e只允许最多出现一次。+/-在e之前只允许最多出现一次,在e之后同样最多出现一次,并且只能在树的最前端
- 我们允许所有的leading和trailing zeros,比如000009和00000.30000都是合法的
- 我们允许所有的leading和trailing whitespaces,但是不允许中间的whitespaces
这些情况都要考虑的话,写出来的代码一定是十分繁杂的,并且很有可能会遗漏,非常不这么推荐这么写。这道题最简单的方式使用regex,如下所示:
- ^(-|\+)?(\d+\.?\d*|\.\d+)(e(-|\+)?\d+)?$
乍看之下有点复杂,但是break down之后思路是很清晰的:
- ^和$代表从头到尾match input string,代表整个input string需要match这个regex pattern,只有substring是不行的
- (-|\+)?代表match正负号一次或者零次
- (\d+\.?\d*|\.\d+)
- 第一部分\d+\.?\d*,\d+代表整数部分,\.?代表零次或者一次小数点,\d*代表零次或者多次数字。也就是说 5, 7.83, 23. 这样的都可以match
- 第二部分\.\d+,代表match没有整数部分的小数,比如.3434
- (e(-|\+)?\d+)?, 这一部分代表科学计数法的部分,总的来说就是一次e后面接整数。最后的?代表整体出现一次或者零次
- e代表match e一次
- (-|\+)? 同上,match正负号一次或者零次
- \d+,match所有整数
所以整个regex是可以cover所有情况的,有兴趣的可以去regex101去试一试。
虽然我们可以用regex解,但这肯定不是expected的解法。regex归根到底也是状态的转移,我们可以用DFA来模拟。我们可以根据以上情况建状态机,基本思路是先建立整数的部分,然后小数的部分,最后科学计数法的部分,状态机如下图所示:
图一
我们可以看出只有最后停在2, 4, 7的状态才是合法的状态。
对于所有的输入来说,我们同样可以给他们标号:
No comments:
Post a Comment