题目来源:https://leetcode.com/problems/valid-number/
问题描述
Hard
Validate if a given string can be interpreted as a decimal number.
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
Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one. However, here is a list of characters that can be in a valid decimal number:
Of course, the context of these characters also matters in the input.
Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition.
------------------------------------------------------------
题意
给定一个字符串,判断是否是合法的数字。数字可以包含’.’和’e’.
------------------------------------------------------------
思路
有限状态自动机的教科书式的题目。构造9个状态START, SIGN0, DIG0, DOT, DIG1, EXP, SIGN1, DIG2, UNVALID,输入的每一个字符,状态发生转换。
除此以外需要注意的有两点呢:
1. 首尾空格是可以忽略的,可以使用java.lang.String.trim方法;
2. 形如”3.”和”3.e-3”的数字也是合法的,因此状态机的参数不仅要考虑当前状态和当前字符输入,还需要考虑当前状态的上一个状态。详见代码Line 71和Line 137.
------------------------------------------------------------
代码
class Solution {
// state descriptor definition
public static final short START = 0;
public static final short SIGN0 = 1;
public static final short DIG0 = 2;
public static final short DOT = 3;
public static final short DIG1 = 4;
public static final short EXP = 5;
public static final short SIGN1 = 6;
public static final short DIG2 = 7;
public static final short UNVALID = -1;
/**
* Finite State Automata
*/
private short fsa(short state, short pre, char ch)
{
switch (state)
{
case START:
if (ch == '+' || ch == '-')
{
return SIGN0;
}
else if (ch >= '0' && ch <= '9')
{
return DIG0;
}
else if (ch == '.')
{
return DOT;
}
else
{
return UNVALID;
}
case SIGN0:
if (ch >= '0' && ch <= '9')
{
return DIG0;
}
else if (ch == '.')
{
return DOT;
}
else
{
return UNVALID;
}
case DIG0:
if (ch >= '0' && ch <= '9')
{
return DIG0;
}
else if (ch == '.')
{
return DOT;
}
else if (ch == 'e')
{
return EXP;
}
else
{
return UNVALID;
}
case DOT:
if (ch >= '0' && ch <= '9')
{
return DIG1;
}
else if (ch == 'e' && pre == DIG0)
{
return EXP;
}
else
{
return UNVALID;
}
case DIG1:
if (ch >= '0' && ch <= '9')
{
return DIG1;
}
else if (ch == 'e')
{
return EXP;
}
case EXP:
if (ch == '+' || ch == '-')
{
return SIGN1;
}
else if (ch >= '0' && ch <= '9')
{
return DIG2;
}
else
{
return UNVALID;
}
case SIGN1:
if (ch >= '0' && ch <= '9')
{
return DIG2;
}
else
{
return UNVALID;
}
case DIG2:
if (ch >= '0' && ch <= '9')
{
return DIG2;
}
else
{
return UNVALID;
}
default:
return UNVALID;
}
}
public boolean isNumber(String s) {
s = s.trim();
short state = START, pre = state;
for (int i = 0, n = s.length(); i