本问题对应的 leetcode 原文链接:剑指 Offer 20. 表示数值的字符串
问题描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
- 若干空格
-
一个 小数 或者 整数
-
(可选)一个
'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
),加号'+'
,减号'-'
,空格' '
或者点'.'
。
解题思路
视频讲解直达: 本题视频讲解
代码实现
class Solution {
public boolean isNumber(String s) {
//有限状态机
// 2.小数点 3.E/e 4. 数字字符 5. -+
if(s == null || s.length() <= 0){
return false;
}
char[] res = s.trim().toCharArray();
if(res.length <= 0) return false;
int n = res.length;
boolean is_dot = false;
boolean is_e_or_E = false;
boolean is_num = false;
for(int i = 0; i < n; i++){
if(res[i] >= '0' && res[i] <= '9'){
is_num = true;
} else if(res[i] == '.'){
//-+ 8. 8.8 .8
// 前面:不能有重复的小数点,也不能出现 e/E
if(is_dot || is_e_or_E){
return false;
}
is_dot = true;
} else if(res[i] == 'e' || res[i] == 'E'){
// 前面必须要有一个数字 || 前面不能出现重复的 e/E
if(is_e_or_E || !is_num){
return false;
}
is_e_or_E = true;
is_num =false;//11E+ 11E
} else if(res[i] == '-' || res[i] == '+'){
if(i!=0 && res[i-1] != 'e' && res[i-1] != 'E'){
return false;
}
} else {
return false;
}
}
return is_num;
}
}
Python
class Solution(object):
def isNumber(self, s):
"""
:type s: str
:rtype: bool
"""
# 有限状态机
# 2.小数点 3.E/e 4.数字字符 5.-+
if s == None or len(s) <= 0:
return False
res = s.strip()
if len(res) <= 0:
return False
n = len(res)
is_dot = False
is_e_or_E = False
is_num = False
for i in range(n):
if res[i] >= '0' and res[i] <= '9':
is_num = True
elif res[i] == '.':
# -+ 8. 8.8 .8
# 前面:不能有重复的小数点,也不能出现 e/E
if is_dot or is_e_or_E:
return False
is_dot = True
elif res[i] == 'e' or res[i] == 'E':
# 前面必须要有一个数字 || 前面不能出现重复的 e/E
if is_e_or_E or not is_num:
return False
is_e_or_E = True
is_num = False #11E+ 11E
elif res[i] == '-' or res[i] == '+':
if i!=0 and res[i-1] != 'e' and res[i-1] != 'E':
return False
else:
return False
return is_num
C++
class Solution {
public:
bool isNumber(string s) {
if (s.empty()) {
return false;
}
// Trim leading and trailing whitespace
s = trim(s);
const char* res = s.c_str();
int n = s.length();
bool is_dot = false;
bool is_e_or_E = false;
bool is_num = false;
for (int i = 0; i < n; i++) {
if (res[i] >= '0' && res[i] <= '9') {
is_num = true;
} else if (res[i] == '.') {
if (is_dot || is_e_or_E) {
return false;
}
is_dot = true;
} else if (res[i] == 'e' || res[i] == 'E') {
if (is_e_or_E || !is_num) {
return false;
}
is_e_or_E = true;
is_num = false;
} else if (res[i] == '-' || res[i] == '+') {
if (i != 0 && res[i - 1] != 'e' && res[i - 1] != 'E') {
return false;
}
} else {
return false;
}
}
return is_num;
}
private:
string trim(const string& s) {
string result = s;
result.erase(result.begin(), find_if(result.begin(), result.end(), [](int ch) {
return !isspace(ch);
}));
result.erase(find_if(result.rbegin(), result.rend(), [](int ch) {
return !isspace(ch);
}).base(), result.end());
return result;
}
};
Go
func isNumber(s string) bool {
/*
:type s: str
:rtype: bool
*/
// 有限状态机
// 2.小数点 3.E/e 4.数字字符 5.-+
if s == "" || len(s) <= 0 {
return false
}
res := strings.TrimSpace(s)
if len(res) <= 0 {
return false
}
n := len(res)
is_dot := false
is_e_or_E := false
is_num := false
for i := 0; i < n; i++ {
if res[i] >= '0' && res[i] <= '9' {
is_num = true
} else if res[i] == '.' {
// -+ 8. 8.8 .8
// 前面:不能有重复的小数点,也不能出现 e/E
if is_dot || is_e_or_E {
return false
}
is_dot = true
} else if res[i] == 'e' || res[i] == 'E' {
// 前面必须要有一个数字 || 前面不能出现重复的 e/E
if is_e_or_E || !is_num {
return false
}
is_e_or_E = true
is_num = false //11E+ 11E
} else if res[i] == '-' || res[i] == '+' {
if i != 0 && res[i-1] != 'e' && res[i-1] != 'E' {
return false
}
} else {
return false
}
}
return is_num
}
JS
/**
* @param {string} s
* @return {boolean}
*/
var isNumber = function(s) {
// 有限状态机
// 2. 小数点 3. E/e 4. 数字字符 5. -+
if (s == null || s.length <= 0) {
return false;
}
let res = s.trim().split('');
if (res.length <= 0) {
return false;
}
let n = res.length;
let is_dot = false;
let is_e_or_E = false;
let is_num = false;
for (let i = 0; i < n; i++) {
if (res[i] >= '0' && res[i] <= '9') {
is_num = true;
} else if (res[i] === '.') {
// -+ 8. 8.8 .8
// 前面:不能有重复的小数点,也不能出现 e/E
if (is_dot || is_e_or_E) {
return false;
}
is_dot = true;
} else if (res[i] === 'e' || res[i] === 'E') {
// 前面必须要有一个数字 || 前面不能出现重复的 e/E
if (is_e_or_E || !is_num) {
return false;
}
is_e_or_E = true;
is_num = false; // 11E+ 11E
} else if (res[i] === '-' || res[i] === '+') {
if (i !== 0 && res[i - 1] !== 'e' && res[i - 1] !== 'E') {
return false;
}
} else {
return false;
}
}
return is_num;
};