算法
(模拟,字符串处理) $O(n)$
- 先去除行首和行尾空格;
- 行首如果有一个正负号,直接忽略;
- 如果字符串为空或只有一个
'.'
,则不是一个合法数; - 循环整个字符串,去掉以下几种情况:
(1)'.'
或'e'
多于1个;
(2)'.'
在'e'
后面出现;
(3)'e'
后面或前面为空,或者'e'
前面紧跟着'.'
;
(4)'e'
后面紧跟着正负号,但正负号后面为空; - 剩下的情况都合法;
时间复杂度分析:整个字符串只遍历一遍,所以时间复杂度是 $O(n)$。
C++ 代码
class Solution {
public:
bool isNumber(string s) {
int i = 0;
while (i < s.size() && s[i] == ' ') i ++ ;
int j = s.size() - 1;
while (j >= 0 && s[j] == ' ') j -- ;
if (i > j) return false;
s = s.substr(i, j - i + 1);
if (s[0] == '-' || s[0] == '+') s = s.substr(1);
if (s.empty() || s[0] == '.' && s.size() == 1) return false;
int dot = 0, e = 0;
for (int i = 0; i < s.size(); i ++ )
{
if (s[i] >= '0' && s[i] <= '9');
else if (s[i] == '.')
{
dot ++ ;
if (e || dot > 1) return false;
}
else if (s[i] == 'e' || s[i] == 'E')
{
e ++ ;
if (i + 1 == s.size() || !i || e > 1 || i == 1 && s[0] == '.') return false;
if (s[i + 1] == '+' || s[i + 1] == '-')
{
if (i + 2 == s.size()) return false;
i ++ ;
}
}
else return false;
}
return true;
}
};
分享一种神奇的指针解法 核心思想为使用一个指针从前往后逐个检查字符串中的字符,合法的字符指针后移,否则不移动,同时使用一个标志变量记录从开始到当前位置的字符串是否为合法的数值,最终输出结果由指针是否移动到字符串末尾和标志变量的值决定
神奇的指针解法
棒。
看完后手动回来点赞!!!
分享一下文法描述的方法 ,https://www.acwing.com/solution/content/42734/
#### 编译原理做法
#### 状态机做法
感觉每次这类题目都束手束脚的,因为总是感觉数据很多种,判断很多种
加油hh 熟能生巧。
题目里写的 +-5的情况是不是漏了
你运行一遍会发现
"+-5"
会返回false
。还是不太清楚+-5是在哪一步被判掉的
手动模拟一遍,别偷懒。
懂了,是在
else return false;
那里判掉的,谢谢y总不客气。
为什么i从前面删了空格,j还要重后面再删一次
这是先把左边多余的空格删掉,再把右边多余的空格删掉。
if (e || dot > 1) return false; 这一句如果改成if (dot || e > 1) return false;
在输入”123.45e+6”的时候会返回false,这是什么原因?
这两句话不是等价的。如果执行了
dot ++
,那么if (dot ||e > 1)
的条件必然成立。0123这样的也是合法的吗?
在这道题目里是合法的。
1.e+5这种是合法的吗?
是合法的
您好, e前面紧跟着“.”的情况,是不是应该是 s[i-1] == ‘.’ 而不是 “ i == 1 && s[0] == ‘.’ ”
不好意思之前忘记回复了,这里
e
前面紧跟这'.'
是指e
的前面只有一个'.'
的情况,像123.e+10
这种情况是合法的。