面试题20. 表示数值的字符串
2020-03-13 本文已影响0人
人一己千
题目
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"0123"及"-1E-16"都表示数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法
正则表达式
这是最简单的方法,因为这就是一个正则题目。不过由于我的正则写的太少。
这是别人的代码:
作者:victoria-zhou
链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/solution/onpythonjie-ti-wu-fa-luo-ji-pan-duan-regexdfadeng-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
import re
class Solution:
p = re.compile(r'^[+-]?(\.\d+|\d+\.?\d*)([eE][+-]?\d+)?$')
def isNumber(self, s: str) -> bool:
return bool(self.p.match(s.strip()))
限定性有限自动机
总结出相应的状态和状态之间的转化函数。
class Solution(object):
def isNumber(self, s):
"""
:type s: str
:rtype: bool
"""
#define DFA state transition tables
states = [{},
# State (1) - initial state (scan ahead thru blanks)
{'blank': 1, 'sign': 2, 'digit':3, '.':4},
# State (2) - found sign (expect digit/dot)
{'digit':3, '.':4},
# State (3) - digit consumer (loop until non-digit)
{'digit':3, '.':5, 'e':6, 'blank':9},
# State (4) - found dot (only a digit is valid)
{'digit':5},
# State (5) - after dot (expect digits, e, or end of valid input)
{'digit':5, 'e':6, 'blank':9},
# State (6) - found 'e' (only a sign or digit valid)
{'sign':7, 'digit':8},
# State (7) - sign after 'e' (only digit)
{'digit':8},
# State (8) - digit after 'e' (expect digits or end of valid input)
{'digit':8, 'blank':9},
# State (9) - Terminal state (fail if non-blank found)
{'blank':9}]
currentState = 1
for c in s:
# If char c is of a known class set it to the class name
if c in '0123456789':
c = 'digit'
elif c in ' \t\n':
c = 'blank'
elif c in '+-':
c = 'sign'
# If char/class is not in our state transition table it is invalid input
if c not in states[currentState]:
return False
# State transition
currentState = states[currentState][c]
# The only valid terminal states are end on digit, after dot, digit after e, or white space after valid input
if currentState not in [3,5,8,9]:
return False
return True
讲道理
- 通过e分割为底数和指数部分;
- 底数只能包含数字正负号和小数点,指数只能包含正负号和数字;
- 正负号出现的话只能在数字的第一个位置;
- 小数点只能有一个;
通过这几条规则的就是正确的答案。
class Solution(object):
def isNumber(self, s):
"""
:type s: str
:rtype: bool
"""
# 分开指数和底数进行判断
s = s.lower().strip()
e_pos = s.find('e')
if e_pos == -1:
print(-1)
return self.judge_d(s)
else:
d_str = s[:e_pos]
p_str = s[e_pos+1:]
return self.judge_d(d_str) and self.judge_p(p_str)
def judge_d(self,num):
result = False
point = False
for i,c in enumerate(num):
if c not in '0123456789+-.':
return False
elif c in '+-' :
if i != 0 : return False
elif c == '.' :
if point: return False
else: point = True
else:
result = True
return result
def judge_p(self,num):
result = False
if num == "":
return False
for i,c in enumerate(num):
if c not in '0123456789+-':
return False
elif c in '+-' :
if i != 0:
return False
else:
result = True
return result