剑指offer53_表示数值的字符串_题解
正则表达式匹配
题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
示例1
输入
"123.45e+6"
返回值
true
示例2
输入
"1.2.3"
返回值
false
分析
方案一:正则表达式
表示数值的字符串遵循如下模式:
\[[𝑠𝑖𝑔𝑛]𝑑𝑖𝑔𝑖𝑡𝑠[.[𝑑𝑖𝑔𝑖𝑡𝑠]][𝑒|𝐸[𝑠𝑖𝑔𝑛]𝑑𝑖𝑔𝑖𝑡𝑠]
\]
('['和']'之间的为可有可无的部分)
转换为正则表达式为
正负号是否出现: [+-]?
整数:(\\d+\\.?)
浮点数:(\\d*\\.\\d+)
如果存在指数部分,那么e或者E肯定出现,+或-可以不出现,紧接着必须跟着整数,或者整个部分都不出现: ([eE][+-]?\\d+)?
Java代码
/**
1.时间复杂度:O(1)
2.空间复杂度:O(1)
**/
public class Solution {
public boolean isNumeric(char[] str) {
String s = new String(str);
String regex="[+-]?((\\d+\\.?)|(\\d*\\.\\d+))([eE][+-]?\\d+)?";
return s.matches(regex);
}
}
方案二:类型转换
Python代码
/**
1.时间复杂度:O(1)
2.空间复杂度:O(1)
**/
class Solution:
def isNumeric(self, s):
try:
x = float(s)
return True
except:
return False
方案三:模拟
C++代码
//逐位遍历
class Solution
{
public:
// 函数scanDigit用来扫描字符串中的0到9的数位
void scanDigits(char **s)
{
while (**s != '\0' && **s >= '0' && **s <= '9')
++(*s);
}
//函数isExponential用来匹配用科学记数法表示的数值的结尾部分
//结尾部分的第一个字符是'e'或者'E',接下来可能有一个正负号,再紧跟着是若干0到9的数位
bool isExponential(char **s)
{
++(*s);
if (**s == '\0')
return false;
if (**s == '+' || **s == '-')
++(*s);
//符号位之后必须跟有其他符号
if (**s == '\0')
return false;
scanDigits(s);
return **s == '\0' ? 1 : 0;
}
bool isNumeric(char *s)
{
if (s == nullptr)
return false;
//看第一个字符是不是正负号,如果是,在字符串上移动一个字符
if (*s == '+' || *s == '-')
++s;
//符号位之后必须跟有其他符号
if (*s == '\0')
return false;
bool numeric = true; //记录科学计数法表示的数值的结尾部分
scanDigits(&s);
if (*s != '\0')
{
//for floats
if (*s == '.')
{
++s;
scanDigits(&s);
if (*s == 'e' || *s == 'E')
numeric = isExponential(&s);
}
// for integers
else if (*s == 'e' || *s == 'E')
numeric = isExponential(&s);
else
numeric = false;
}
// 记录科学计数法表示的数值的结尾部分
return numeric && *s == '\0';
}
};