Validate if a given string is numeric.
Some examples:
"0"
=> true
" 0.1 "
=> true
"abc"
=> false
"1 a"
=> false
"2e10"
=> true
Our solution:
This problem deals with a common problem in compilers in the lexical analysis, i.e. knowing if a certain string is a valid token.We accept the following regular grammar, shown as UNIX regular expression by simplicity:
\s*[\+\-]?(([0-9]+(\.[0-9]*)?)|\.[0-9]+)([eE][+-]?[0-9]+)?\s*
where \s represents [ \t].
This regular expression is accepted by the underneath DFA(Deterministic Finite Automata):
where any transition not shown takes to an error state, that in the code is represented by -1.
public class Solution { public boolean isNumber(String s) { int state = 0; for(int i=0; i<s.length();i++) { state=getNextState(state, s.charAt(i)); if (state==-1) return false; } state = getNextState(state, ' '); return state == 8; } private int getNextState(int state, char c) { int[][] transitionTable = { {0,2,1,3,-1,-1}, {-1,2,-1,3,-1,-1}, {8,2,-1,4,5,-1}, {-1,4,-1,-1,-1,-1}, {8,4,-1,-1,5,-1}, {-1,7,6,-1,-1,-1}, {-1,7,-1,-1,-1,-1}, {8,7,-1,-1,-1,-1}, {8,-1,-1,-1,-1,-1}}; return transitionTable[state][getSymbol(c)]; } private int getSymbol(char c) { switch(c) { case ' ': case '\t': return 0; case '0': case '1': case '2':case '3': case '4': case '5': case '6': case '7': case '8': case '9': return 1; case '+': case '-': return 2; case '.': return 3; case 'E': case 'e': return 4; default: return 5; } } }
More information:
[1, Chapter 1] J. Glen Brookshear, "Theory of Computation: Formal Languages, Automata, and Complexity", Addison-Wesley.
[2, Chapters 2-3] Rajeev Motwani, Jeffrey Ullman, and John Hopcroft, "Introduction to Automata Theory, Languages, and Computation", Addison-Wesley.
This comment has been removed by the author.
ReplyDeleteExcellent work!
ReplyDeleteExcellent work!
ReplyDelete