1、题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
2、代码详解
力扣通过版
用3个标志位met_dot, met_e, met_digit来分别标记是否遇到了“.”,“e/E”和任何0-9的数字。
class Solution(object):
def isNumber(self, s):
"""
:type s: str
:rtype: bool
"""
s = s.strip()
met_dot = met_e = met_digit = False
for i, char in enumerate(s):
if char in ('+', '-'):
if i > 0 and s[i-1] != 'e' and s[i-1] != 'E':
return False
elif char == '.':
if met_dot or met_e:
return False
met_dot = True
elif char == 'e' or char == 'E':
if met_e or not met_digit:
return False
met_e, met_digit = True, False # e后必须接,所以这时重置met_digit为False,以免e为最后一个char
elif char.isdigit():
met_digit = True
else:
return False
return met_digit
牛客能通过但力扣不行
# -*- coding:utf-8 -*-
class Solution:
# s字符串
def isNumeric(self, s):
if s == None or len(s) <= 0:
return False
# 将字符依次遍历,并转小写
word = [w.lower() for w in s] # 如['5', 'e', '2']形式
# 如果包含'e'
if 'e' in word:
# 根据e的位置,将其切割成两部分
indexE = word.index('e')
front = word[:indexE]
behind = word[indexE+1:]
# 指数部分不合法的情况
if '.' in behind or len(behind) == 0:
return False
isFront = self.scanDigit(front)
isBehind = self.scanDigit(behind)
return isFront and isBehind
# 如果不包含'e'
else:
isNumber = self.scanDigit(word)
return isNumber
def scanDigit(self, word):
dotNum = 0 # '.'出现次数
vocabulary = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '-', '.', 'e'] # 数值字符串元素“词表”
for i in range(len(word)):
if word[i] not in vocabulary:
return False
if word[i] == '.':
dotNum += 1
# '+-'必须出现在首位,isNumber函数以'e'分割的妙处凸显
if word[i] in '+-' and i != 0:
return False
if dotNum > 1: # 出现多个小数点
return False
return True
s = Solution()
print(s.isNumeric('5e2'))
print(s.isNumeric('12e'))
print(s.isNumeric('1.2.3'))
print(s.isNumeric('+-5'))
print(s.isNumeric('12e+5.4'))