一、题目描述
请实现一个函数用来判断是否表示数值(包括整数和小数)
例如:
字符串:“+100”、“5e2”、“-123”、“3.1416”、“-1E-16”都表示数值
字符串:“12e”、“la3.14”、“1.2.3”、“+-5”、以及"12e+5.4"都不是
二、解题思路
不考虑字符串有多余空格的前提下,此题主要关注点如下:
1)字符串开头可能会有“+”或者“-”号
2)处理完1)之后,会跟着一串数字,走完数字后
a)情况一:是小数
后面可能会有小数点,小数点之后
aa)可能后面全是数字,一直到串尾
bb)可能后面跟着“E”或者“e”,接下来就是科学计数法判定
b)情况二:是科学计数数
做科学计数法判定
c)情况三:走完数字直接到串尾--说明就是单纯的数字
3)科学计数法判定
把一个数表示成a(1≤a<10,n为整数)与10的幂相乘的形式,这种记数法叫做科学记数法。计算器或电脑表达10的幂是一般是用E或e,也就是1.99714E13=19971400000000
所以满足科学计数法的特点主要有以下几点:
a)“E”或“e”前面为整数或者小数
b)“E”或“e”后面紧跟着一串整数数字(可以有正负号),但一定不能为小数
综合上述分析,下面的代码打算将科学计数法判定规则单独写一个function,考虑到代码的简洁和可读性,将数字的判定操作也单独写在一个function里。
三、算法实现
class Solution:
def isNumber(self, s: str) -> bool:
# 按数字的规则对字符串进行扫描
def scan_number(s, start_index):
res_index = start_index
while start_index < len(s) and (s[start_index] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']):
start_index += 1
return start_index, res_index == start_index
def scientific_judge(s, start_index):
s_len = len(s)
if start_index >= s_len:
return start_index, False
# e/E 后面允许有 +/-号
if s[start_index] == '+' or s[start_index] == '-':
start_index += 1
# 进行数字扫描
start_index, status = scan_number(s, start_index)
# ‘+’ / '-’ 后面必须要有数字 "4e+"就不是
if status:
return start_index, False
# E”或“e”后面紧跟着一串整数数字(可以有正负号),但一定不能为小数
# 所以数字结束了直接到串尾,则为合法数,反之就不是科学计数
return start_index, start_index == s_len
# 去掉前后空格
s = s.strip()
s_len = len(s)
if s_len == 0:
return False
# 开头可以是'+' or '-'
i = 0
if s[i] == '+' or s[i] == '-':
i += 1
# 走一串数字
i, status_one = scan_number(s, i)
judge = True
# 走完一串数字后,对小数和科学计数分别进行处理
if i < s_len:
# 小数情况判断
if s[i] == '.':
i += 1
i, status_two = scan_number(s, i)
# '.'后面没有数字,且'.’前面也没有数字
if status_two and status_one:
return False
if i < s_len and (s[i] == 'e' or s[i] == 'E'):
i += 1
i, judge = scientific_judge(s, i)
# e / E 前面必须要有数字
elif status_one == False and (s[i] == 'e' or s[i] == 'E'):
i += 1
i, judge = scientific_judge(s, i)
# 数字走完后如果后面还有其他非法字符,则直接return false
else:
return False
return judge & (i == s_len)
梦想还是要有的,万一实现了呢~~~~~ヾ(◍°∇°◍)ノ゙~~~~~~~~~~