题目
题目来源:leetcode 剑指Offer 20:表示数值的字符串
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,
“+100”、“5e2”、"-123"、“3.1416”、"-1E-16"、"0123"等是数值字符串;
“12e”、“1a3.14”、“1.2.3”、“±5”、"12e+5.4"等不是数值字符串。
解题思路
数值字符串的结构:a.bec
或a.bEc
。其中a
为带符号整型,b
为无符号整型,c
为带符号整型。写代码时,注意以下原则:
(1)
数值字符串不可以为空。
(2)
可以忽略数值字符串前后的空白符。
(3)
如果存在小数点,则小数点.
的前后至少有一处是数值,即a
和b
至少存在一个。如1.
、.1
和1.1
是数值,但.
不是数值。
(4)
如果存在e
或E
,则它的前面和后面都不能没有数值,即a.b
和c
都不能为空。
从左到右遍历字符串,程序的大体思路是:
(1)
过滤字符串前面的空白符。
(2)
判断a
是否为空。
(3)
如果存在小数点,判断b
是否为空,如果a
和b
都为空的话返回false
。
(4)
如果不存在小数点,且a
为空的话返回false
。
(5)
如果存在e
或E
,判断c
是否为空,是的话返回false
。
(6)
如果c
后面存在非空字符,返回false
。
(7)
返回true
。
代码实现(C++)
class Solution {
public:
bool isNumber(string s) {
const char *head = fsp(s.c_str());
// a
const char *str = fs(head);
if (str != head) {
++head;
}
str = fi(str);
if (*str == '.') {
++str;
// b
str = fi(str);
if (head + 1 == str) {
return false;
}
}
else {
if (str == head) {
return false;
}
}
// e/E
if (*str == 'e' || *str == 'E') {
++str;
head = str;
// c
str = fs(str);
if (str != head) {
++head;
}
str = fi(str);
}
if (str == head) {
return false;
}
str = fsp(str);
return *str == '\0';
}
const char* fsp(const char *str) { // 过滤空格
while (*str == ' ') {
++str;
}
return str;
}
const char* fs(const char *str) { // 过滤符号
if (*str == '+' || *str == '-') {
++str;
}
return str;
}
const char* fi(const char *str) { // 过滤整型(无符号)
while (*str >= '0' && *str <= '9') {
++str;
}
return str;
}
};