剑指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';
    }
};
posted @ 2021-02-20 17:13  RiverCold  阅读(39)  评论(0编辑  收藏  举报