题目:
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
- 若干空格
- 一个 小数 或者 整数
- (可选)一个
'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
),加号'+'
,减号'-'
,空格' '
或者点'.'
。
方法一:正则匹配:
#include<regex>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param str string字符串
* @return bool布尔型
*/
bool isNumeric(string str) {
regex reg("^\\s*[+-]?((\\d+)|(\\d*\\.\\d+)|(\\d+\\.\\d*))([eE][+-]?\\d+)?\\s*$");
smatch result;
return regex_match(str, result, reg);
// write code here
}
};
方法一:分析:
采用正则匹配,文档地址:正则表达式手册
方法二:状态机
方法二:代码
/*
* @lc app=leetcode.cn id=100290 lang=cpp
*
* [剑指 Offer 20] 表示数值的字符串
*/
// @lc code=start
class Solution {
public:
enum{start, frontSpace, sign, digit, dot, E, backSpace, finish, OUT};
bool isSign(char c){
return c == '+' || c == '-';
}
bool isDigit(char c){
return '0' <= c && c <= '9' ;
}
bool isE(char c){
return c == 'E' || c == 'e' ;
}
bool isDot(char c){
return c == '.' ;
}
bool isSpace(char c){
return c == ' ' ;
}
bool isNumber(string s) {
int i = 0, status = start;
bool onceE = false, onceDot = false, DigitDot= false, EDot = false;
while (i < s.length())
{
char c = s[i];
switch (status)
{
case start:
case frontSpace:
status = isSpace(c) ? frontSpace : (isDigit(c) ? digit : (isSign(c) ? sign : (isDot(c) && !onceDot ? dot:OUT)));
break;
case sign:
status = isDigit(c) ? digit : (isDot(c) && !onceDot ? dot : OUT);
break;
case digit:
status = isDigit(c) ? digit : (isE(c) && !onceE ? E : (isDot(c) && !onceDot ? dot : (isSpace(c)? backSpace : OUT)));
if(status == dot) {
//标记数字跟小数点情况
DigitDot = true;
if(onceE) EDot = true;
}
break;
case E:
//标记只有一个e情况
onceE = true;
status = isSign(c) ? sign : (isDigit(c) ? digit: OUT) ;
break;
case backSpace:
status = isSpace(c) ? backSpace : OUT;
break;
case dot:
//标记只有一个.情况
onceDot = true;
status = isDigit(c) ? digit : (isSpace(c) ? backSpace : (isE(c) ? E:OUT));
//标记数字跟小数点情况
if(status == digit) DigitDot = true;
break;
case OUT:
default:
return false;
break;
}
i++;
}
//排除e后跟小数点情况
if(EDot) return false;
//排除只有一个点的情况
if( onceDot && !DigitDot ) return false;
//正常结尾条件
if(status == digit || status == backSpace || (status == dot && DigitDot) ) return true;
return false;
}
};
// @lc code=end