JZ20 表示数值的字符串

题目:

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

数值(按顺序)可以分成以下几个部分:

  1. 若干空格
  2. 一个 小数 或者 整数
  3. (可选)一个 'e' 或 'E' ,后面跟着一个 整数
  4. 若干空格

小数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+' 或 '-'
  2. 下述格式之一:
    1. 至少一位数字,后面跟着一个点 '.'
    2. 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
    3. 一个点 '.' ,后面跟着至少一位数字

整数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+' 或 '-'
  2. 至少一位数字

部分数值列举如下:

  • ["+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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值