标签:leetcode
链接:https://leetcode.com/problems/valid-number/
问题描述:
Validate if a given string is numeric.
Some examples:
“0” => true
” 0.1 ” => true
“abc” => false
“1 a” => false
“2e10” => true
Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.
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.
Hide Tags Math String
验证一个字符串是不是一个数字。一开始我的算法流程如下:
1 字符串首尾得的空格去掉;
2 找字符串中有没有e,有e的话将字符串分为e前一个和e后一个。
3 如果有e,分别判断两个数字是否合法。如果没有e,直接判断数字是否合法
这样的步骤会导致判断过程中逻辑非常混乱,而且极容易出现bug,代码看起来、改起来都十分的吃力。虽然能AC,但是这种方法并不可取。代码如下:
class Solution {
public:
bool isNumber(string s){
s.erase(0,s.find_first_not_of(" "));
s.erase(s.find_last_not_of(" ") + 1);
int exp1=s.find_first_of(‘e‘);
int exp2=s.find_last_of(‘e‘);
string str1="",str2="";
if(exp2!=exp1||exp2==s.size())
return false;
if(exp1!=-1)
{
if(misnumber(s.substr(exp1+1,s.size()-exp1-1))==false)
return false;
s=s.substr(0,exp1);
}
int point=s.find_first_of(‘.‘);
if(point>-1)
{
if(point==0)
s[0]=‘+‘;
else if(point==s.size()-1)
s=s.substr(0,point);
else
s=s.substr(0,point)+s.substr(point+1,s.size()-1-point);
}
return misnumber(s);
}
bool misnumber(string s)
{
if(s=="")return false;
if(s.size()>0)
{
if(s[0]==‘-‘||s[0]==‘+‘)
{
s=s.substr(1);
}
}
if(s.size()>0)
{
for(int i=0;i<s.size();i++)
{
if(!(s[i]-‘0‘<10&&s[i]-‘0‘>-1))
return false;
}
return true;
}
else
return false;
}
};
这一题可以用有限状态机来求解,用这个方法的关键是找到一个转移矩阵。首先枚举所有的可能出现的数字的情况:
0 初始状态
1 符号
2 数字
3 点
4 数字+点
5 数字+E
6 点+数字
7 数字+E+符号
8 数字+E+数字
先给出我的转移矩阵:
int transitionTable[][5] =
{
-1, 1, 2, 3, -1, //state0
-1, -1, 2, 3, -1, //state1
-1, -1, 2, 4, 5, //state2
-1, -1, 6, -1, -1, //state3
-1, -1, 4, -1, 5, //state4
-1, 7, 8, -1, -1, //state5
-1, -1, 6, -1, 5, //state6
-1, -1, 8, -1, -1, //state7
-1, -1, 8, -1, -1, //state8
};
可以明确输入,INVALID表示无效的输入,SIGN表示符号,DIGIT表示数字,DOT表示点,EXPONENT表示E。
enum InputType
{
INVALID, // 0
SIGN, // 1
DIGIT, // 2
DOT, // 3
EXPONENT, // 4
};
来看转移矩阵到底怎么用比如在初始状态0,如果遇到如果遇到INVALID,状态转换为-1(-1表示这个字符串表示数字不合法)。如果遇到SIGN状态转换为1。如果遇到DIGIT状态转化为2。如果遇到DOT则状态转换为3。如果遇到EXPONENT状态转换为-1。从这里就可以知道状态转移矩阵是个二维矩阵,一个维度是状态的维度,另一个矩阵是输入的维度。
转换后只要检查当前的状态就可以判断是否合法,状态2,4,6,8是合法的。
class Solution
{
public:
bool isNumber(string s)
{
enum InputType
{
INVALID, // 0
SIGN, // 1
DIGIT, // 2
DOT, // 3
EXPONENT, // 4
};
s.erase(0,s.find_first_not_of(" "));
s.erase(s.find_last_not_of(" ") + 1);
int transitionTable[][5] =
{
-1, 1, 2, 3, -1, //state0
-1, -1, 2, 3, -1, //state1
-1, -1, 2, 4, 5, //state2
-1, -1, 6, -1, -1, //state3
-1, -1, 4, -1, 5, //state4
-1, 7, 8, -1, -1, //state5
-1, -1, 6, -1, 5, //state6
-1, -1, 8, -1, -1, //state7
-1, -1, 8, -1, -1, //state8
};
int state = 0;
for(int i=0;i<s.size();i++)
{
InputType inputType = INVALID;
if (s[i] == ‘+‘ || s[i] == ‘-‘)
inputType = SIGN;
else if (isdigit(s[i]))
inputType = DIGIT;
else if (s[i] == ‘.‘)
inputType = DOT;
else if (s[i] == ‘e‘ || s[i] == ‘E‘)
inputType = EXPONENT;
state = transitionTable[state][inputType];
if (state == -1)
return false;
}
return state == 2 || state == 4 || state == 6 || state == 8;
}
};
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:leetcode
原文地址:http://blog.csdn.net/efergrehbtrj/article/details/46789405