题目:
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
- 若干空格
- 一个 小数 或者 整数
- (可选)一个
'e'
或'E'
,后面跟着一个 整数 - 若干空格
小数(按顺序)可以分成以下几个部分:
- (可选)一个符号字符('+' 或 '-')
- 下述格式之一:
- 至少一位数字,后面跟着一个点 '.'
- 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
- 一个点 '.' ,后面跟着至少一位数字
整数(按顺序)可以分成以下几个部分:
- (可选)一个符号字符('+' 或 '-')
- 至少一位数字
部分数值列举如下:
- ["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]
部分非数值列举如下:
- ["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]
思路:
首先明确判断标准:
1.包含的元素1-9,+-,e,小数点
2.小数点,只能包含一个,可以在最前面和最后面
3.正负号,在没有e的时候 正负号只能在最前面,且只能有一个
4.e,e的后面只能是整数,e的前后都有数字
5.不能为空,不能只有'+-e.'
函数的整体思路是在遍历字符串的过程种,记录下4种关键信息
- 是否包含数字
- 是否包含小数点,记录小数点的坐标
- 是否包含正负号
- 是否包含e,记录e的坐标
(因为小数点和e只能出现一次,所以可以把坐标记录下来,正负号可以出现多次,但是出现的位置有特定要求,所以直接判断即可),再通过一定的判断 即可判断是否是数值。
代码:
class Solution(object):
def isNumber(self, s):
"""
:type s: str
:rtype: bool
"""
s = s.strip()
if s == '':
return False
v1 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '-', 'e', 'E', '.']
v2 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
v3 = ['+', '-']
v4 = ['e', 'E']
v5 = '.'
# 包含的元素1 - 9, +-, e, 小数点
# 小数,正负号,包含E,正整数
f_flag, pm_flag, have_e,i_flag = False, False, False,False
index = 0
pm_index = []
for i in s:
if i in v2:
index += 1
i_flag =True
continue
elif i == v5: # 小数点, 只能包含一个
if f_flag: return False
f_flag = True
dot_index = index
elif i in v3:
if index != 0 and not (have_e and index == e_index + 1):
return False
elif i in v4:
if have_e: return False
have_e = True
e_index = index
else:
return False
index += 1
if not i_flag:return False
if have_e: # 包含e
if f_flag and dot_index > e_index: return False
if s[:e_index] in ['.','+','-'] or s[e_index+1:] in ['.','+','-']:
return False
if e_index == 0 or e_index == len(s) - 1: return False
return True
else: # 不包含e
if f_flag and s in ['.','+','-']:return False
return True
参考链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/solution/jian-zhi-offer-20-biao-shi-shu-zhi-de-zi-gok6/