这道题目有点类似于atoi
(将字符串转化为整数),回想一下atoi
:如果第一个非空格字符不存在或者不是数字也不是正负号则返回零,否则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。
这道题目里面我们采取以下步骤:
- 忽略前置空格和后置空格
- 正负号只能出现在最前面
- 句点只能出现一次
- 不能含有正负号、句点、数字以外的字符
- 不能为空
- 不能是单独的正负号或句点
如果是科学计数法,需要符合:
- 没有空格紧邻e
- e的前面是数字
- e的后面是整数
具体的实现方案:
- 先判断是否包含e
- 如果包含e,则先判断e的前后是否紧邻空格
- 如果是的,返回false
- 如果不是,判断e的前面是否为数字,后面是否为整数
- 如果不包含e,直接判断是否为数字
- 为了实现方便,定义了一个
help
函数,它会返回三个可能的值,0表示非数字,1表示整数,2表示小数
代码如下:
// // Created by jt on 2020/9/26. // class Solution { public: bool isNumber(const char *s) { // 判断是否含有e const char *p = s; while (*p) { if (*p == 'e') break; ++p; } if (*p) { // 如果含有e,先判断e的前后是否有空格 if (p-1 >= s && *(p-1) != ' ' && *(p+1) && *(p+1) != ' ') return help(s, p) > 0 && help(p+1, nullptr) == 1; else return false; } return help(s, nullptr) > 0; } int help(const char *s, const char *end) { // 返回0表示非数字 返回1表示整数 返回2表示小数 if (s == end) return 0; // 忽略前置空格 while (*s == ' ') ++s; // 如果只有空格 if (!(*s)) return 0; // 记录正负号和句点 bool hasSign = false, hasDot = false, hasNum = false; if (*s == '+' || *s == '-') { hasSign = true; ++s; } while (*s && *s != ' ' && s != end) { if (hasSign && (*s == '+' || *s == '-')) return 0; if (hasDot && *s == '.') return 0; if (*s == '.') { hasDot = true; ++s; continue; } if (*s < '0' || *s > '9') return 0; hasNum = true; ++s; } // 忽略后置空格 while (*s && s != end) { if (*s != ' ') return 0; ++s; } if (hasNum && !hasDot) return 1; if (hasNum && hasDot) return 2; return 0; } };