class Solution {
public:
bool isNumber(string s) {
}
};
剑指 Offer 20. 表示数值的字符串
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
'e'
或 'E'
,后面跟着一个 整数小数(按顺序)可以分成以下几个部分:
'+'
或 '-'
)'.'
'.'
,后面再跟着至少一位数字'.'
,后面跟着至少一位数字整数(按顺序)可以分成以下几个部分:
'+'
或 '-'
)部分数值列举如下:
["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]
部分非数值列举如下:
["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]
示例 1:
输入:s = "0" 输出:true
示例 2:
输入:s = "e" 输出:false
示例 3:
输入:s = "." 输出:false
示例 4:
输入:s = " .1 " 输出:true
提示:
1 <= s.length <= 20
s
仅含英文字母(大写和小写),数字(0-9
),加号 '+'
,减号 '-'
,空格 ' '
或者点 '.'
。原站题解
python3 解法, 执行用时: 40 ms, 内存消耗: 15.1 MB, 提交时间: 2022-11-13 13:50:13
class Solution: def isNumber(self, s: str) -> bool: states = [ { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank' { 'd': 2, '.': 4 } , # 1. 'sign' before 'e' { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot' { 'd': 3, 'e': 5, ' ': 8 }, # 3. 'digit' after 'dot' { 'd': 3 }, # 4. 'digit' after 'dot' (‘blank’ before 'dot') { 's': 6, 'd': 7 }, # 5. 'e' { 'd': 7 }, # 6. 'sign' after 'e' { 'd': 7, ' ': 8 }, # 7. 'digit' after 'e' { ' ': 8 } # 8. end with 'blank' ] p = 0 # start with state 0 for c in s: if '0' <= c <= '9': t = 'd' # digit elif c in "+-": t = 's' # sign elif c in "eE": t = 'e' # e or E elif c in ". ": t = c # dot, blank else: t = '?' # unknown if t not in states[p]: return False p = states[p][t] return p in (2, 3, 7, 8)
golang 解法, 执行用时: 4 ms, 内存消耗: 5.5 MB, 提交时间: 2022-11-13 13:49:38
type State int type CharType int const ( STATE_INITIAL State = iota STATE_INT_SIGN STATE_INTEGER STATE_POINT STATE_POINT_WITHOUT_INT STATE_FRACTION STATE_EXP STATE_EXP_SIGN STATE_EXP_NUMBER STATE_END ) const ( CHAR_NUMBER CharType = iota CHAR_EXP CHAR_POINT CHAR_SIGN CHAR_SPACE CHAR_ILLEGAL ) func toCharType(ch byte) CharType { switch ch { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': return CHAR_NUMBER case 'e', 'E': return CHAR_EXP case '.': return CHAR_POINT case '+', '-': return CHAR_SIGN case ' ': return CHAR_SPACE default: return CHAR_ILLEGAL } } func isNumber(s string) bool { transfer := map[State]map[CharType]State{ STATE_INITIAL: map[CharType]State{ CHAR_SPACE: STATE_INITIAL, CHAR_NUMBER: STATE_INTEGER, CHAR_POINT: STATE_POINT_WITHOUT_INT, CHAR_SIGN: STATE_INT_SIGN, }, STATE_INT_SIGN: map[CharType]State{ CHAR_NUMBER: STATE_INTEGER, CHAR_POINT: STATE_POINT_WITHOUT_INT, }, STATE_INTEGER: map[CharType]State{ CHAR_NUMBER: STATE_INTEGER, CHAR_EXP: STATE_EXP, CHAR_POINT: STATE_POINT, CHAR_SPACE: STATE_END, }, STATE_POINT: map[CharType]State{ CHAR_NUMBER: STATE_FRACTION, CHAR_EXP: STATE_EXP, CHAR_SPACE: STATE_END, }, STATE_POINT_WITHOUT_INT: map[CharType]State{ CHAR_NUMBER: STATE_FRACTION, }, STATE_FRACTION: map[CharType]State{ CHAR_NUMBER: STATE_FRACTION, CHAR_EXP: STATE_EXP, CHAR_SPACE: STATE_END, }, STATE_EXP: map[CharType]State{ CHAR_NUMBER: STATE_EXP_NUMBER, CHAR_SIGN: STATE_EXP_SIGN, }, STATE_EXP_SIGN: map[CharType]State{ CHAR_NUMBER: STATE_EXP_NUMBER, }, STATE_EXP_NUMBER: map[CharType]State{ CHAR_NUMBER: STATE_EXP_NUMBER, CHAR_SPACE: STATE_END, }, STATE_END: map[CharType]State{ CHAR_SPACE: STATE_END, }, } state := STATE_INITIAL for i := 0; i < len(s); i++ { typ := toCharType(s[i]) if _, ok := transfer[state][typ]; !ok { return false } else { state = transfer[state][typ] } } return state == STATE_INTEGER || state == STATE_POINT || state == STATE_FRACTION || state == STATE_EXP_NUMBER || state == STATE_END }
python3 解法, 执行用时: 292 ms, 内存消耗: 15.2 MB, 提交时间: 2022-11-13 13:49:18
from enum import Enum class Solution: def isNumber(self, s: str) -> bool: State = Enum("State", [ "STATE_INITIAL", "STATE_INT_SIGN", "STATE_INTEGER", "STATE_POINT", "STATE_POINT_WITHOUT_INT", "STATE_FRACTION", "STATE_EXP", "STATE_EXP_SIGN", "STATE_EXP_NUMBER", "STATE_END" ]) Chartype = Enum("Chartype", [ "CHAR_NUMBER", "CHAR_EXP", "CHAR_POINT", "CHAR_SIGN", "CHAR_SPACE", "CHAR_ILLEGAL" ]) def toChartype(ch: str) -> Chartype: if ch.isdigit(): return Chartype.CHAR_NUMBER elif ch.lower() == "e": return Chartype.CHAR_EXP elif ch == ".": return Chartype.CHAR_POINT elif ch == "+" or ch == "-": return Chartype.CHAR_SIGN elif ch == " ": return Chartype.CHAR_SPACE else: return Chartype.CHAR_ILLEGAL transfer = { State.STATE_INITIAL: { Chartype.CHAR_SPACE: State.STATE_INITIAL, Chartype.CHAR_NUMBER: State.STATE_INTEGER, Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT, Chartype.CHAR_SIGN: State.STATE_INT_SIGN }, State.STATE_INT_SIGN: { Chartype.CHAR_NUMBER: State.STATE_INTEGER, Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT }, State.STATE_INTEGER: { Chartype.CHAR_NUMBER: State.STATE_INTEGER, Chartype.CHAR_EXP: State.STATE_EXP, Chartype.CHAR_POINT: State.STATE_POINT, Chartype.CHAR_SPACE: State.STATE_END }, State.STATE_POINT: { Chartype.CHAR_NUMBER: State.STATE_FRACTION, Chartype.CHAR_EXP: State.STATE_EXP, Chartype.CHAR_SPACE: State.STATE_END }, State.STATE_POINT_WITHOUT_INT: { Chartype.CHAR_NUMBER: State.STATE_FRACTION }, State.STATE_FRACTION: { Chartype.CHAR_NUMBER: State.STATE_FRACTION, Chartype.CHAR_EXP: State.STATE_EXP, Chartype.CHAR_SPACE: State.STATE_END }, State.STATE_EXP: { Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER, Chartype.CHAR_SIGN: State.STATE_EXP_SIGN }, State.STATE_EXP_SIGN: { Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER }, State.STATE_EXP_NUMBER: { Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER, Chartype.CHAR_SPACE: State.STATE_END }, State.STATE_END: { Chartype.CHAR_SPACE: State.STATE_END }, } st = State.STATE_INITIAL for ch in s: typ = toChartype(ch) if typ not in transfer[st]: return False st = transfer[st][typ] return st in [State.STATE_INTEGER, State.STATE_POINT, State.STATE_FRACTION, State.STATE_EXP_NUMBER, State.STATE_END]