扫码关注微信公众号
回复“面试手册”,获取本站PDF版
回复“简历”,获取高质量简历模板
回复“加群”,加入程序员交流群
回复“电子书”,获取程序员类电子书
题目描述
请实现一个函数用来判断字符串是否表示 数值 (包括整数和小数)。
数值 (按顺序)可以分成以下几个部分:
- 若干空格
- 一个 小数 或者 整数
- (可选)一个 ‘e’ 或 ‘E’ ,后面跟着一个 整数
- 若干空格
小数 (按顺序)可以分成以下几个部分:
- (可选)一个符号字符(’+’ 或 ‘-‘)
- 下述格式之一:
- 至少一位数字,后面跟着一个点 ‘.’
- 至少一位数字,后面跟着一个点 ‘.’ ,后面再跟着至少一位数字
- 一个点 ‘.’ ,后面跟着至少一位数字
整数 (按顺序)可以分成以下几个部分:
- (可选)一个符号字符(’+’ 或 ‘-‘)
- 至少一位数字
部分 数值 列举如下:
["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]
部分 非数值 列举如下:
["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]
示例 1:
输入:s = "0"
输出:true
示例 2:
输入:s = "e"
输出:false
示例 3:
输入:s = "."
输出:false
示例 4:
输入:s = " .1 "
输出:true
提示:
- 1 <= s.length <= 20
- s 仅含英文字母(大写和小写),数字(0-9),加号 ‘+’ ,减号 ‘-‘ ,空格 ‘ ‘ 或者点 ‘.’ 。
算法
(模拟) O(n)
算法步骤:
- 先去除行首和行尾空格;
- 行首如果有一个正负号,直接忽略;
- 如果字符串为空或只有一个’.’,则不是一个合法数;
- 循环整个字符串,去掉以下几种情况: (1) ‘.’或’e’多于1个; (2) ‘.’在’e’后面出现; (3) ‘e’后面或前面为空,或者’e’前面紧跟着’.’; (4) ‘e’后面紧跟着正负号,但正负号后面为空;
- 剩下的情况都合法;
时间复杂度
O(n)
空间复杂度
O(1)
C++ 代码
class Solution {
public:
bool isNumber(string s) {
/* 1. 去前后空格 */
// 去掉前空格
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);
/* 2. 行首如果有一个正负号直接忽略 */
if (s[0] == '+' || s[0] == '-') s = s.substr(1);
/* 3. 如果字符串为空,或者只有一个 .,则不是一个合法数 */
if (s.empty() || s[0] == '.' && s.size() == 1) return false; // +, -, .
/* 4. 循环整个字符串,去掉以下几种情况:
(1) '.'或'e'多于1个;
(2) '.'在'e'后面出现;
(3) 'e'后面或前面为空,或者'e'前面紧跟着'.';
(4) 'e'后面紧跟着正负号,但正负号后面为空; */
// 字符串中点和 e 的数量
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; // 21.1.1.2, 12e122.22
}
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; // 122e+ 或 122e-
i ++ ;
}
}
// 不合法的字符就直接返回 false
else return false;
}
/* 5. 其余情况都合法 */
return true;
}
};
Java 代码
public class Solution {
public boolean isNumber(String s) {
/* 1. 去前后空格 */
// 去掉前空格
int i = 0;
while (i < s.length() && s.charAt(i) == ' ') i ++ ;
// 去掉前后空格
int j = s.length() - 1;
while (j >= 0 && s.charAt(j) == ' ') j -- ;
// 删完空格后字符串不合法
if (i > j) return false;
s = s.substring(i, j + 1);
/* 2. 行首如果有一个正负号直接忽略 */
if (s.charAt(0) == '+' || s.charAt(0) == '-') s = s.substring(1);
/* 3. 如果字符串为空,或者只有一个 .,则不是一个合法数 */
if (s.isEmpty() || (s.charAt(0) == '.' && s.length() == 1)) return false; // +, -, .
/* 4. 循环整个字符串,去掉以下几种情况:
(1) '.'或'e'多于1个;
(2) '.'在'e'后面出现;
(3) 'e'后面或前面为空,或者'e'前面紧跟着'.';
(4) 'e'后面紧跟着正负号,但正负号后面为空; */
// 字符串中点和 e 的数量
int dot = 0, e = 0;
for (i = 0; i < s.length(); i ++ )
{
if (s.charAt(i) >= '0' && s.charAt(i) <= '9') ;
else if (s.charAt(i) == '.')
{
dot ++ ;
if (e > 0 || dot > 1) return false; // 21.1.1.2, 12e122.22
}
else if (s.charAt(i) == 'e' || s.charAt(i) == 'E')
{
e ++ ;
if (i + 1 == s.length() || i == 0 || e > 1 || (i == 1 && s.charAt(0) == '.')) return false;
if (s.charAt(i + 1) == '+' || s.charAt(i + 1) == '-')
{
if (i + 2 == s.length()) return false; // 122e+ 或 122e-
i ++ ;
}
}
// 不合法的字符就直接返回 false
else return false;
}
/* 5. 其余情况都合法 */
return true;
}
}
Python 代码
class Solution:
def isNumber(self, s: str) -> bool:
# 1. 去前后空格
i = 0
while i < len(s) and s[i] == ' ':
i += 1
j = len(s) - 1
while j >= 0 and s[j] == ' ':
j -= 1
if i > j:
return False
s = s[i:j+1]
# 2. 行首如果有一个正负号直接忽略
if s[0] == '+' or s[0] == '-':
s = s[1:]
# 3. 如果字符串为空,或者只有一个 .,则不是一个合法数
if not s or (s[0] == '.' and len(s) == 1):
return False
dot = 0
e = 0
i = 0
while i < len(s):
c = s[i]
if '0' <= c <= '9':
i += 1
elif c == '.':
dot += 1
if e or dot > 1:
return False # 21.1.1.2, 12e122.22
i += 1
elif c == 'e' or c == 'E':
e += 1
if i + 1 == len(s) or i == 0 or e > 1 or (i == 1 and s[0] == '.'):
return False
if s[i + 1] == '+' or s[i + 1] == '-':
if i + 2 == len(s):
return False # 122e+ 或 122e-
i += 2
else:
i += 1
else:
return False # 不合法的字符就直接返回 false
# 5. 其余情况都合法
return True
本文由读者提供,Github地址:https://github.com/tonngw
点击面试手册,获取本站面试手册PDF完整版