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.
个人感觉题目思路很清晰,但是难点在于有很多一开始没想到的测试数据,而题目没有给出明确的“Valid Number”的定义,所以只能不断提交来根据错误的数据更新代码(提交了20次才AC,sad)
class Solution {
public:
bool isNumber(string s)
{
int len = s.length();
//去除两边的空格,提取中间的部分,并初步判断合法性
string NewStr = "";
int it = 0;
while(s[it] == ' ')
it++;
while(it<len && s[it]!=' ')
NewStr += s[it++];
//后面剩余部分是否全是空格
while(it < len)
{
if(s[it] != ' ')
return false;
it++;
}
len = NewStr.length();
if(len == 0) //字符串为空
return false;
if(NewStr[0]=='-' || NewStr[0]=='+') //去除首位正负号的影响
{
NewStr = NewStr.substr(1,len-1);
len--;
}
int DotFlag = 0, EFlag = 0;
for(int i=0;i<len;i++)
{
if(NewStr[i] == '.')
DotFlag++;
if(NewStr[i]=='e' || NewStr[i]=='E')
EFlag++;
}
//e或者 . 的位置、数量有问题 _________测试数据里 ".3" "3." 全认为是正确的
if(NewStr[0]=='e' || NewStr[len-1]=='e' || DotFlag>1 || EFlag>1)
return false;
//全是数字
if(DotFlag==0 && EFlag==0)
{
for(int i=0;i<len;i++)
if(!(NewStr[i]>='0' && NewStr[i]<='9'))
return false;
return true;
}
//只有一个小数点
if(DotFlag==1 && EFlag==0)
{
if(len == 1) //只有一个小数点,没有数字
return false;
for(int i=0;i<len;i++)
{
if(NewStr[i] == '.')
{
DotFlag = i; break;
}
}
//小数点前后是否全是数字
for(int i=0;i<DotFlag;i++)
if(!(NewStr[i]>='0' && NewStr[i]<='9'))
return false;
for(int i=DotFlag+1;i<len;i++)
if(!(NewStr[i]>='0' && NewStr[i]<='9'))
return false;
return true;
}
else
{
for(int i=0;i<len;i++)
{
if(NewStr[i] == 'e')
{
EFlag = i; break;
}
}
int SignFlag = -1;
//次幂
if(NewStr[EFlag+1]=='-' || NewStr[EFlag+1]=='+')
SignFlag = EFlag+1;
if(SignFlag == len-1) //最后一位是符号
return false;
//仅仅是科学计数法,无小数点
if(EFlag && DotFlag==0)
{
for(int i=0;i<len;i++)
{
if(i==EFlag || i==SignFlag)
continue;
else
{
if(!(NewStr[i]>='0' && NewStr[i]<='9'))
return false;
}
}
return true;
}
else //科学计数法加小数点
{
for(int i=0;i<len;i++)
{
if(NewStr[i] == '.')
{
DotFlag = i; break;
}
}
if(DotFlag==0 && EFlag==1) //针对 .e3 这样的情况
return false;
if(DotFlag > EFlag) //针对 3e. 这样的情况
return false;
for(int i=0;i<len;i++)
{
if(i==EFlag || i==SignFlag || i==DotFlag)
continue;
else
{
if(!(NewStr[i]>='0' && NewStr[i]<='9'))
return false;
}
}
return true;
}
}
}
};
以及评论区的简短代码:
bool isNumber(const char *s)
{
int i = 0;
// skip the whilespaces
for(; s[i] == ' '; i++) {}
// check the significand
if(s[i] == '+' || s[i] == '-') i++; // skip the sign if exist
int n_nm, n_pt;
for(n_nm=0, n_pt=0; (s[i]<='9' && s[i]>='0') || s[i]=='.'; i++)
s[i] == '.' ? n_pt++:n_nm++;
if(n_pt>1 || n_nm<1) // no more than one point, at least one digit
return false;
// check the exponent if exist
if(s[i] == 'e') {
i++;
if(s[i] == '+' || s[i] == '-') i++; // skip the sign
int n_nm = 0;
for(; s[i]>='0' && s[i]<='9'; i++, n_nm++) {}
if(n_nm<1)
return false;
}
// skip the trailing whitespaces
for(; s[i] == ' '; i++) {}
return s[i]==0; // must reach the ending 0 of the string
}