题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
思路一:
设定符号、小数点、e是否出现的标志变量,依次从e、符号、小数点开始判断,最后判断是否是有效数字。但该方法也存在一些不足,例如:-.123和+ 均判断为true。
代码一:
class Solution {
public:
bool isNumeric(char* string) {
//标记符号、小数点、e是否出现
bool sign = false;
bool point = false;
bool hasE = false;
for(int i = 0; i < strlen(string); ++i) {
if(string[i] == 'e' || string[i] == 'E') {
if(i == strlen(string) - 1) return false; //e后面一定要接数字
if(hasE) return false; //不能同时出现两个e
hasE = true;
} else if(string[i] == '+' || string[i] == '-') {
//第二次出现‘+’、‘-’必须紧跟在e的后面
if(sign && string[i-1] != 'e' && string[i-1] != 'E') return false;
//第一次出现‘+’、‘-’,且不是在字符串开头,也必须紧跟在e的后面
if(!sign && i > 0 && string[i-1] != 'e' && string[i-1] != 'E') return false;
sign = true;
} else if(string[i] == '.') {
//e后面不能接小数点,小数点不能出现两次
if(hasE || point) return false;
point = true;
} else if(string[i] < '0' || string[i] > '9') {
return false;
}
}
return true;
}
};
思路二:
构建两个子函数,分别用来扫描数据到第一次出现非数字字符,以及检测科学计数法的结尾部分(以E或e开头)是否合理。这里的处理运用到了指针以及指针的指针,目的是为了通过子函数对原数据进行修改。
代码二:
class Solution {
public:
void scanDigits(char** string) {
//用来扫描字符串中的0到9的数位
while(**string != '\0' && **string >= '0' && **string <= '9') {
++(*string);
}
}
bool isExp(char** string) {
//检测科学计数法结尾部分,该部分以e或E开头
if(**string != 'e' && **string != 'E') {
return false;
}
++(*string);
if(**string == '+' || **string == '-') {
++(*string);
}
if(**string == '\0') {
return false;
}
scanDigits(string);
return (**string == '\0') ? true : false;
}
bool isNumeric(char* string) {
if(string == NULL) return false;
if(*string == '+' || *string == '-') {
++string;
}
if(*string == '\0') return false;
bool numeric = true;
scanDigits(&string);
if(*string != '\0') {
//如果是浮点数
if(*string == '.') {
++string;
scanDigits(&string);
if(*string == 'e' || *string == 'E') {
//由于此处调用后,需要改变*string的内容,因此形参必须为char**,即指向指针string的指针
//子函数改变形参,如果需要保存对形参p的修改状态,则需要传入p的地址,即指向p的指针&p作为形参变量
numeric = isExp(&string);
}
}
//如果是整数
else if(*string == 'e' || *string == 'E') {
numeric = isExp(&string);
}
//非法数
else {
numeric = false;
}
}
return numeric && (*string == '\0');
}
};