思路
这道题主要是要全面考虑测试用例
设输入的原字符串为str
首先:str不能为空,如果为空返回假。为了访问字符串上的字符,还要定义一个flag变量来记录此时访问的字符,初值为0
之后还要考虑空格问题
eg:" 0.2123"
所以当字符串不为空时先处理字符串的空格
同理处理完空格后还要判空防止“ ”全是空格的串
其次还要考虑到’+‘‘-’字符的问题
可能出现这两个字符的位置为整数与指数这两个位置
eg:
+100 -1E-16 -1E+16
还要注意到表示指数有两种字母E/e
整数部分
如果出现+/-跳过这个字符
确定这部分是否有整数字符:
定义两个变量begin与end,这两个变量的初值与flag相同,如果遇到‘0’到‘9’的字符end++。如果end>begin时表示有整数。
因为判断是否有整数字符在小数部分以及指数部分要用,所以将其定义为函数
如果有整数部分返回true否则返回false
小数部分
当遇到 . 时flag++跳过小数点
小数部分不可能有+/-
小数有特殊情况如:
0.34与.34相同。如果整数部分是0则可以省略
34.0与34.相同。如果小数部分是0则可以省略
当小数部分有数字时返回true否则返回false
根据上面分析当遇到小数点时
整数部分或者小数部分有整数就行
所以逻辑关系为整数部分||小数部分
指数部分
当遇到E/e时flag++跳过E/e
指数部分可能有+/-
指数部分来讲前面必须有整数数字
eg:
.e1 e1都不是合法的字符串
指数部分后面必须有整数数字
eg:
12e 12e1.2都不是合法字符
上述的判断存在整数在整数部分已经写成函数直接调用即可
注意:
最后匹配成功时flag一定指向字符串的结尾
eg:".1."
如果不加这个条件就出错了
C++代码
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param str string字符串
* @return bool布尔型
*/
bool isNumeric(string str) {
// write code here
if(str.empty())
return false;
string strTmp;//储存去空后的字符串
for(int i=0;i<str.size();i++)
{
if(str[i]!=' ')
{
strTmp.push_back(str[i]);
}
}
if(strTmp.empty())//去空后还要判空
return false;
int flag=0;
bool number=IsNumber(strTmp,flag);//可能存在+-号调用IsNumber
if(!strTmp.empty()&&strTmp[flag]=='.')
{
flag++;//跳过小数点
number=IsUnsNumber(strTmp,flag)||number;
//不可能存在+-调用IsUnNumber
}
if(!strTmp.empty()&&(strTmp[flag]=='E'||strTmp[flag]=='e'))
{
flag++;//可能存在+-号调用IsNumber
number=number&&IsNumber(strTmp,flag);
}
return number&&flag==strTmp.size();
}
private:
bool IsUnsNumber(string& str,int&flag)
{
int begin=flag;
while(!str.empty()&&(str[flag]>='0'&&str[flag]<='9'))
{
++flag;
}
return flag>begin;
}
bool IsNumber(string& str,int& flag)
{
if(str[flag]=='+'||str[flag]=='-')
{
++flag;
}
return IsUnsNumber(str,flag);
}
};