请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
例如,字符串"+100"
,"5e2"
,"-123"
,"3.1416"
和"-1E-16"
都表示数值。
但是"12e"
,"1a3.14"
,"1.2.3"
,"+-5"
和"12e+4.3"
都不是。
注意:
- 小数可以没有整数部分,例如.123等于0.123;
- 小数点后面可以没有数字,例如233.等于233.0;
- 小数点前面和后面可以有数字,例如233.666;
- 当e或E前面没有数字时,整个字符串不能表示数字,例如.e1、e1;
- 当e或E后面没有整数时,整个字符串不能表示数字,例如12e、12e+5.4;
数据范围
输入字符串长度 [0,25][0,25]。
字符串中不含空格。
样例:
输入: "0"
输出: true
题目描述
判断一个字符串是否可以表示成一个合法的数字,中间可以包含正负号,小数点以及e或E
使用指针巧解表示数值的字符串
核心思想为使用一个指针从前往后逐个检查字符串中的字符是否合法,如果合法,则指针后移,否则指针停止移动,显然如果字符串是合法的,这个指针应该移动到字符串的最末尾
同时在移动指针的过程中判断从字符串开始到当前位置的字符子串是否是合法的数值,并将它存储在isNum中,显然isNum记录了指针所指位置的字符子串是否能表示为数值的信息
指针的最终位置和isNum的值决定最终的结果
class Solution {
public:
bool isNumber(string s) {
s += '\0'; //指针移动过程中,最后会有一位的溢出,加上一位空字符防止字符串下标越界
bool isNum = false; //该变量表示从0开始,到i位置的字符串是否构成合法数字,初始化为false
int i = 0; //检测指针初始化为0
while(s[i] == ' ') ++i; //滤除最前面的空格,指针后移
if(s[i] == '+' || s[i] == '-') ++i; //一个‘-’或‘+’为合法输入,指针后移
while(s[i] >= '0' && s[i] <= '9'){ //此处如果出现数字,为合法输入,指针后移,同时isNum置为true
isNum = true; //显然,在此处,前面的所有字符是可以构成合法数字的
++i;
}
if(s[i] == '.') ++i; //按照前面的顺序,在此处出现小数点也是合法的,指针后移(此处能否构成合法字符取决于isNum)
while(s[i] >= '0' && s[i] <= '9'){ //小数点后出现数字也是合法的,指针后移
isNum = true; //无论前面是什么,此处应当是合法数字
++i;
}
//上面的部分已经把所有只包含小数点和正负号以及数字的情况包括进去了,如果只判断不含E或e的合法数字,到此处就可以停止了
if(isNum && (s[i] == 'e' || s[i] == 'E')){ //当前面的数字组成一个合法数字时(isNum = true),此处出现e或E也是合法的
++i;
isNum = false; //但到此处,E后面还没有数字,根据isNum的定义,此处的isNum应等于false;
if(s[i] == '-' || s[i] == '+') ++i; //E或e后面可以出现一个‘-’或‘+’,指针后移
while(s[i] >= '0' & s[i] <= '9') {
++i;
isNum = true; //E后面接上数字后也就成了合法数字
}
}
//如果字符串为合法数字,指针应当移到最后,即是s[i] == '\0' 同时根据isNum判断数字是否 合法
//整个过程中只有当i位置处的输入合法时,指针才会移动
return (s[i] == '\0' && isNum);
}
};