这道题目有点类似于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;
}
};
京公网安备 11010502036488号