题目描述
判断一个数字是否有效,可以分为以下几部分:
- 是一个小数或者整数
- (可选)存在e或者E,后面跟着一个数字
小数时:
- (可选)一个符号位'+'或者'-'
- 下列格式之一
- 至少一位数字,跟着一个'.'
- 至少一位数字,跟着一个'.',后面至少跟着一位数字
- 一个'.',后面跟着一位数字。
整数时:
- (可选)一个符号位'+'或者'-'
- 至少一位数字
思路:状态机
那**+12.34e+3**来举例,可以知道存在以下状态和转移路线
状态
- 初始状态
- 符号状态
- 数字状态
- 左边有小数点状态
- 左边无小数点状态
- 小数部分
- e
- 指数符号
- 指数数字
输入类型 0. 符号
- 数字
- 点
- e
- 其他
转移方程如下
0:in符号->1,in数字->2,in点->4
1:in数字->2,in点->4,ine->6
2:in数字->2,in点->3,ine->6
3:in数字->5,ine->6
4:in数字->5
5:in数字->5,ine->6
6:in符号->7,in数字->8
7:in数字->8
8:in数字->8
输入其他:错误状态
最终的有效状态:2,3,5,8
代码实现
class Solution {
private:
enum State{
STATE_INITLAL,
STATE_SYMBOL,
STATE_INT,
STATE_POINT_LEFT_WITH_INT,
STATE_POINT_LEFT_WITHOUT_INT,
STATE_FRATCTION,
STATE_EXP,
STATE_EXP_SYMBOL,
STATE_EXP_INT
};
enum CharType{
CHARTYPE_SYMBOL,
CHARTYPE_INT,
CHARTYPE_POINT,
CHARTYPE_E,
CHARTYPE_ERROR,
};
CharType char_type(char c){
if(c >= '0' && c <= '9'){
return CHARTYPE_INT;
} else if(c == '+' || c== '-'){
return CHARTYPE_SYMBOL;
} else if(c == 'e' || c == 'E'){
return CHARTYPE_E;
} else if (c == '.'){
return CHARTYPE_POINT;
} else {
return CHARTYPE_ERROR;
}
}
public:
unordered_map<State, unordered_map<CharType, State>> transf{
{
STATE_INITLAL,{
{CHARTYPE_SYMBOL, STATE_SYMBOL},
{CHARTYPE_INT, STATE_INT},
{CHARTYPE_POINT, STATE_POINT_LEFT_WITHOUT_INT}
}
},
{
STATE_SYMBOL,{
{CHARTYPE_INT, STATE_INT},
{CHARTYPE_POINT, STATE_POINT_LEFT_WITHOUT_INT}
}
},
{
STATE_INT,{
{CHARTYPE_INT,STATE_INT},
{CHARTYPE_POINT, STATE_POINT_LEFT_WITH_INT},
{CHARTYPE_E, STATE_EXP}
}
},
{
STATE_POINT_LEFT_WITH_INT,{
{CHARTYPE_INT, STATE_FRATCTION},
{CHARTYPE_E, STATE_EXP}
}
},
{
STATE_POINT_LEFT_WITHOUT_INT,{
{CHARTYPE_INT, STATE_FRATCTION}
}
},
{
STATE_FRATCTION,{
{CHARTYPE_INT, STATE_FRATCTION},
{CHARTYPE_E, STATE_EXP}
}
},
{
STATE_EXP,{
{CHARTYPE_SYMBOL, STATE_EXP_SYMBOL},
{CHARTYPE_INT, STATE_EXP_INT}
}
},
{
STATE_EXP_SYMBOL,{
{CHARTYPE_INT, STATE_EXP_INT}
}
},
{
STATE_EXP_INT,
{
{CHARTYPE_INT, STATE_EXP_INT}
}
}
};
unordered_set<State> valid{STATE_INT, STATE_POINT_LEFT_WITH_INT, STATE_FRATCTION, STATE_EXP_INT};
bool isNumber(string s) {
State state = STATE_INITLAL;
for(auto c : s){
CharType type = char_type(c);
if(transf[state].find(type) == transf[state].end()){
return false;
}
state = transf[state][type];
}
return valid.find(state) != valid.end();
}
};