题目描述:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、“5e2”、"-123"、“3.1416”、"-1E-16"、“0123"都表示数值,但"12e”、“1a3.14”、“1.2.3”、"±5"及"12e+5.4"都不是。
解题思路:
其实也不算啥解题思路,只是把能出现的所有不合法的情况排除掉,就是正确答案了
- 首先要出去前后的空格符
- 判断第0位是否为符号位,如果是,则记录已经有了符号位,然后去除符号位
- 科学计数法‘e’,‘E’只能出现一个,用has_e记录是否有e
- 小数点也只能出现一个,e后面只能是整数(可正可负),用has_point记录是否有小数点
- 科学计数法前面必须要有数值,不能为空,不能只有小数点,用has_number记录是否有数值
- 正负号可以出现两次,因为前面已经去除符号位了,所以如果出现正负号,必须要紧跟e后面,否则为false,并且正负号不能为最后一位。
- 小数点只能出现一次,并且小数点前面不能有e,小数点前面可以没有数字,但是可以有符号位。但是不能单独只有小数点,小数点前面或者后面必须有一个有数字。
同样一道题目,在牛客上能过,在leetcode过不了,卡了好几个样例,然后发挥我的if else大法,卡一个样例干一个……具体都在代码中了……
'.1 ’ true : 前后空格不算,小数点可以在第0位,但是要保证小数点后面有数字
‘3.’ true :小数点可以在最后一位,但是要保证小数点前面有数
‘.’ false :只有小数点,不可以
‘.e1’ false :如果有e,前面必须要有数值,不能为空,不能只有小数点
‘4e+’ false :e后面可以有符号位,但是符号位不能为最后一位
def isNumber(s):
s = s.strip() #去除前后的空格
if not s:
return False
if not (s[0] == '+' or s[0] == '-' or s[0] == '.' or s[0].isdigit()):
return False
else:
has_sign = False
if s[0] == '+' or s[0] == '-':
s = s[1:]
has_sign = True
has_e = False
has_point = False
has_number = False
for i in range(len(s)):
if s[i] == 'e' or s[i] == 'E':
if has_e: #说明前面已经出现过e了
return False
elif has_number == False: #e 前面必须要有数字
return False
else:
has_e = True
if i == len(s) - 1: #如果最后一位是e,也是错的
return False
elif s[i] == '+' or s[i] == '-':
if i == 0 or not(s[i-1] == 'e' or s[i-1] == 'E') :
#如果前一位不是e,或者没有前一位,也是错的
return False
elif i == len(s) -1: #如果+是最后一位,也是错的
return False
elif s[i] == '.':
# 遇到小数点,如果不是第一个小数点,则是错的。并且小数点前面不能有e。因为e后面只能跟正整数或负整数
if has_point:
return False
else:
has_point = True
if has_e:
return False
# elif (i == 0 and not has_sign) or not s[i-1].isdigit():
elif not (i == 0 or s[i-1].isdigit()) :
#如果不是第0位(都是在去掉了符号位之后的第0位),或者前面不是数字,这为false
return False
elif i == 0 and i == len(s)-1 :
# 又是第0位,又是最后一位,即只有一个小数点,没有数字,则也是错的
return False
else:
if not s[i].isdigit():
return False
has_number = True
return True
print(isNumber('4e+ ')) #'.1'true , #'3.'true ,#'.'false #'.e1' false, #‘4e+’, false