LeetCode 65. Valid Number(有限状态自动机)

本文详细解析了LeetCode上的经典题目——判断一个字符串是否为有效数字。通过构建有限状态自动机(FSM),文章阐述了如何处理包含'.', 'e', '+' 和 '-' 的复杂情况,确保准确识别各种合法的十进制数形式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目来源:https://leetcode.com/problems/valid-number/

问题描述

65. Valid Number

Hard

Validate if a given string can be interpreted as a decimal number.

Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
" -90e3   " => true
" 1e" => false
"e3" => false
" 6e-1" => true
" 99e2.5 " => false
"53.5e93" => true
" --6 " => false
"-+3" => false
"95a54e53" => false

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one. However, here is a list of characters that can be in a valid decimal number:

  • Numbers 0-9
  • Exponent - "e"
  • Positive/negative sign - "+"/"-"
  • Decimal point - "."

Of course, the context of these characters also matters in the input.

Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition.

------------------------------------------------------------

题意

给定一个字符串,判断是否是合法的数字。数字可以包含’.’’e’.

------------------------------------------------------------

思路

有限状态自动机的教科书式的题目。构造9个状态START, SIGN0, DIG0, DOT, DIG1, EXP, SIGN1, DIG2, UNVALID,输入的每一个字符,状态发生转换。

除此以外需要注意的有两点呢:

1. 首尾空格是可以忽略的,可以使用java.lang.String.trim方法;

2. 形如”3.”和”3.e-3”的数字也是合法的,因此状态机的参数不仅要考虑当前状态和当前字符输入,还需要考虑当前状态的上一个状态。详见代码Line 71和Line 137.

------------------------------------------------------------

代码

class Solution {
    // state descriptor definition
    public static final short START = 0;
    public static final short SIGN0 = 1;
    public static final short DIG0 = 2;
    public static final short DOT = 3;
    public static final short DIG1 = 4;
    public static final short EXP = 5;
    public static final short SIGN1 = 6;
    public static final short DIG2 = 7;
    public static final short UNVALID = -1;
    /**
    * Finite State Automata
    */
    private short fsa(short state, short pre, char ch)
    {
        switch (state)
        {
            case START:
                if (ch == '+' || ch == '-')
                {
                    return SIGN0;
                }
                else if (ch >= '0' && ch <= '9')
                {
                    return DIG0;
                }
                else if (ch == '.')
                {
                    return DOT;
                }
                else
                {
                    return UNVALID;
                }
            case SIGN0:
                if (ch >= '0' && ch <= '9')
                {
                    return DIG0;
                }
                else if (ch == '.')
                {
                    return DOT;
                }
                else
                {
                    return UNVALID;
                }
            case DIG0:
                if (ch >= '0' && ch <= '9')
                {
                    return DIG0;
                }
                else if (ch == '.')
                {
                    return DOT;
                }
                else if (ch == 'e')
                {
                    return EXP;
                }
                else
                {
                    return UNVALID;
                }
            case DOT:
                if (ch >= '0' && ch <= '9')
                {
                    return DIG1;
                }
                else if (ch == 'e' && pre == DIG0)
                {
                    return EXP;
                }
                else
                {
                    return UNVALID;
                }
            case DIG1:
                if (ch >= '0' && ch <= '9')
                {
                    return DIG1;
                }
                else if (ch == 'e')
                {
                    return EXP;
                }
            case EXP:
                if (ch == '+' || ch == '-')
                {
                    return SIGN1;
                }
                else if (ch >= '0' && ch <= '9')
                {
                    return DIG2;
                }
                else
                {
                    return UNVALID;
                }
            case SIGN1:
                if (ch >= '0' && ch <= '9')
                {
                    return DIG2;
                }
                else
                {
                    return UNVALID;
                }
            case DIG2:
                if (ch >= '0' && ch <= '9')
                {
                    return DIG2;
                }
                else
                {
                    return UNVALID;
                }
            default:
                return UNVALID;
        }
    }
    
    public boolean isNumber(String s) {
        s = s.trim();
        short state = START, pre = state;
        for (int i = 0, n = s.length(); i<n; i++)
        {
            short tmp = state;
            state = fsa(state, pre, s.charAt(i));
            pre = tmp;
            if (state == -1)
            {
                return false;
            }
        }
        return state == DIG0 || state == DIG1 || state == DIG2 || (pre == DIG0 && state == DOT);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值