题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+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'); } };