题目描述
Validate if a given string can be interpreted as a decimal number.
Here is a list of characters that can be in a valid decimal number:
Numbers: 0-9
Exponent: "e"
Positive/negative sign: "+"/"-"
Decimal point: "."
Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
" -90e3 " => true
" 1e" => false
"e3" => false
" 6e-1" => true
" 99e2.5 " => false
"53.5e93" => true
" --6 " => false
"-+3" => false
"95a54e53" => false
解题思路
题目的意思是判断一个字符串是否是一个有效的数字,我觉得首先是要明确什么是一个有效的数字,题目说的比较含糊,只是给了几个例子。根据我的尝试,总结了一下有效数字的定义。
这里有效的数字是一个实数,而且满足下面的结构定义:
# Realnum : (SignDec)e(Integer) | SignDec # SignDec : -(Decimal) | +(Decimal) | Decimal # Decimal : (Primary).(Primary) | (Primary) | .(Primary) | (Primary). # Integer : -(Primary) | +(Primary) | Primary # Primary : Numbers | (Numbers)(Primary) # Numbers : 0 | 1 | ... | 9 | 格式上有一些乱,主要是一些关系不好表示,解释一下 1. 一个十进制实数要么是带指数或者是一个带符号的小数 eg: -23e-4, 4e3, -3.23 2. 一个带符号小数是一个带'+'号或者'-'号的小数,或者不带符号的小数 eg: +34.34, -435.1, 342 3. 一个小数是两个无符号整数之间加一个小数点'.'构成,或者一个无符号整数(Primary),或者省略小数点前后的0 eg: 0.1234, .12(等于0.12), 45.1, 4.(等于4.0) 4. 一个有符号整数是一个带'+'号或者'-'号的无符号整数,或者不带符号,其实这个定义包含在了小数中,但是因为指数格式不能是小数,为了方便所以还需要一个单独的定义 eg: +12, -34, 56 5. 一个无符号整数是由数字序列构成的,这里省略了无符号整数的定义。 eg: 32, 324, 897 6. 数字序列要么是一个数字,或者一个数字加上一个数字序列,是一个递归定义 eg: 3, 5, 9, 2, 3454, 1212
根据这个实数的定义,可以比较简单写出判断有效数字的算法,这里的算法实现使用的语言是python3,因为python的字符串相对与C/C++容易操作,从而可以更好地体现算法的思想,而不必关注太多的细节。
算法实现
根据有效的数字的结构,逐层分解字符串,来判断是否满足该结构。要注意的是需要要去除字符串首部和尾部的空白符。
这道题在leetcode上,使用的上面的程序结构。
class Solution: def isNumber(self, s: str) -> bool: ## 判断是否是一个有效的数字 def Realnum(numstr): if numstr == '': return False index = numstr.find('e') if index == -1: return Sign(numstr, 1) elif index == 0 or index == len(numstr)-1: return False else: return Sign(numstr[:index], 1) and Sign(numstr[index+1:], 0) ## 判断带符号数字,根据mode来确定是小数还是整数 def Sign(numstr, mode): i = 0 if numstr[i] == '+' or numstr[i] == '-': i += 1 if mode == 0: return Primary(numstr[i:]) else: return Decimal(numstr[i:]) ## 判断无符号小数 def Decimal(numstr): index = numstr.find('.') if index == -1: return Primary(numstr) elif index == 0: return Primary(numstr[index+1:]) elif index == len(numstr)-1: return Primary(numstr[:index]) else: return Primary(numstr[:index]) and Primary(numstr[index+1:]) ## 判断是否是数字序列 def Primary(numstr): return numstr.isnumeric() ## 忽略串尾和串头的空格 s = s.lstrip() s = s.rstrip() return Realnum(s)
Realnum
对于一个字符串s,首先在串s中查找指数字符'e'
如果没有查找到,那么判断是否是一个带符号小数
否则,判断找到的下标index
如果index不是第一个或者最后一个位置,判断字符'e'之前的子串是否为一个带符号小数,'e'之后的串是否为一个带符号整数Sign
将串前面的符号去掉,然后将参数送往不同的处理函数中:无符号小数或者无符号整数Decimal
对于已经分解好的字符串,在串中查找小数点符号'.',根据查找的结果(小数点的位置),来处理去掉小数点后的子串