Last active
August 11, 2019 06:31
-
-
Save coodoo/5ac793523db56b8f399595d69d020a2e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const T = { | |
INT: 'INT', | |
SIGN: 'SIGN', | |
DOT: 'DOT', | |
EXPO: 'EXPO', | |
SPACE: 'SPACE', | |
INVALID: 'INVALID', | |
EMPTY: 'EMPTY', | |
} | |
let currentState = 'EMPTY' | |
let last = null | |
let excludes = [] | |
const trans = (event) => { | |
// console.log( '\ttrans:', event ) | |
switch(currentState){ | |
// 第一次進入 | |
case 'EMPTY': | |
switch(event){ | |
case 'EXPO': | |
currentState = 'PENDING' | |
break | |
default: | |
currentState = event | |
last = event | |
} | |
break | |
// 只要遇到一次 invalid,後面就都無效了 | |
case 'SPACE': | |
case 'INVALID': | |
currentState = 'INVALID' | |
break | |
// 現在是數字的話 | |
case 'INT': | |
switch(event){ | |
case 'INT': | |
case 'DOT': | |
// debugger // | |
if(excludes.includes(event)){ | |
currentState = 'INVALID' | |
}else{ | |
currentState = event | |
} | |
break | |
case 'EXPO': | |
currentState = 'PENDING' | |
break | |
default: | |
currentState = 'INVALID' | |
} | |
last = event | |
break | |
// 現在是 SIGN | |
case 'SIGN': | |
switch(event){ | |
case 'INT': | |
case 'EXPO': | |
currentState = event | |
break | |
default: | |
currentState = 'INVALID' | |
} | |
last = event | |
break | |
// 現在是 DOT | |
case 'DOT': | |
switch(event){ | |
case 'INT': | |
case 'EXPO': | |
currentState = event | |
break | |
default: | |
currentState = 'INVALID' | |
} | |
last = event | |
break | |
// 現在是 expo | |
case 'EXPO': | |
switch(event){ | |
case 'INT': | |
case 'SIGN': | |
currentState = event | |
break | |
default: | |
currentState = 'PENDING' | |
} | |
last = event | |
break | |
case 'PENDING': | |
switch(event){ | |
case 'INT': | |
case 'SIGN': | |
// e3 已有 e,後面又出現 3,要檢查 e 前方是否有數字才算合格 | |
currentState = last == 'INT' || last == 'EXPO' ? event : 'INVALID' | |
break | |
default: | |
currentState = 'INVALID' | |
} | |
last = event | |
break | |
default: | |
debugger | |
} | |
if(currentState === 'PENDING' || currentState === 'EXPO'){ | |
excludes.push('DOT') | |
} | |
} | |
// 判斷字元的型別 | |
const inputType = c => { | |
// console.log( '\tc=', c ) | |
if(isNaN(+c) === false){ | |
return 'INT' | |
} else if (c === '+' || c === '-') { | |
return 'SIGN' | |
} else if (c === '.') { | |
return 'DOT' | |
} else if (c === 'e') { | |
return 'EXPO' | |
} else if (c === ' ') { | |
return 'SPACE' | |
} else{ | |
return 'INVALID' | |
} | |
} | |
// 進入點 | |
const isNumber = input => { | |
input | |
.trim() | |
.split('') | |
.forEach(c => { | |
// console.log( '\nbefore: ', currentState ) | |
trans(inputType(c)) | |
// console.log( 'after: ', currentState ) | |
}) | |
return currentState | |
} | |
// 跑一堆測試,要全通過 | |
const tests = [ | |
'9e2.5', | |
'1e', | |
'1e3', | |
'e3', | |
'0', | |
' 0.1', | |
'abc', | |
'1 a', | |
'2e10', | |
'-90e3', | |
' 6e-1', | |
' 99e.25', | |
' 99e2.5', | |
'53.5e93', | |
' --6', | |
'-+3', | |
'95a54e53', | |
'12e+-34', | |
'1234', | |
'12+34', | |
'12-34', | |
'12e+34', | |
'12e34', | |
] | |
.forEach( str => { | |
currentState = 'EMPTY' | |
last = null | |
excludes = [] | |
const res = isNumber(str) | |
const res2 = res == 'INVALID' || res == 'PENDING' | |
console.log( isNaN(Number(str)) == res2, str, Number(str), res ) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment