[LeetCode]Valid Number

题目:

Validate if a given string is numeric.

Some examples:
“0” => true
” 0.1 ” => true
“abc” => true
“2e10” => true

思路:

方法1 :直接使用正则表达式regx = “[-+]?(\d+\.?|\.\d+)\d*(e[-+]?\d+)?”,简单粗暴!

方法2 :如果不用正则,就采用 确定有穷状态自动机(DFA),代码简洁有效。不过这里要提前了解一点图论知识。
所谓“确定有穷状态”,必然需要我们自己动手构造出所有状态来,如下所示:

* 0 初始无输入或者只有space的状态

* 1 输入了数字之后的状态

* 2 前面无数字,只输入了dot的状态

* 3 输入了+/-状态

* 4 前面有数字和有dot的状态

* 5 'e' or 'E'输入后的状态

* 6 输入e之后输入+/-的状态

* 7 输入e后输入数字的状态

输入类型我们定义为:
INVALID, // 1. invalid input
SIGN,// 2. ‘+’ or ‘-’
DIGIT,// 3. digits
DOT,// 4. ‘.’
EXP// 5. ‘e’
一共8种状态,然后我们需要根据状态来确定它们的转移,如下图所示:
这里写图片描述
在9种状态中,我们可以发现只有1、4、7四种状态是合法的,所以题目迎刃而解,只要挨个遍历字符,通过判断遍历到最后一个字符时的状态即可确定该字符串是否合法。 在编程中,我们可以简单地用一个邻接矩阵来存储上图转移关系。 这里,我们用个二维数组来表示这表示这个状态转移矩阵。

代码

方法1:

public class Solution {
    /**
    * 判断指定字符串是否为数字
    * @param s 字符串
    * @return true:是数字 false:不是数字
    */
    public boolean isNumber(String s) {
        s = s.trim();
        if (s.isEmpty()) {
            return false;
        }

        //正则匹配
        Pattern p = Pattern.compile(
                "^([+-])?((\\d+)(\\.)?(\\d+)?|(\\d+)?(\\.)?(\\d+))(e([+-])?(\\d+))?$");
        Matcher m = p.matcher(s);
        if (m.find()) {
            return true;
        }

        return false;
    }
}

方法2:

public class ReserveWord {
    final int INVALID = 0;
    final int SIGN = 1;
    final int DIGIT = 2;
    final int DOT = 3;
    final int EXP = 4;

    final int[][] transitionTable = {
            {-1, 3, 1, 2, -1},
            {-1, -1, 1, 4, 5},
            {-1, -1, 4, -1, -1},
            {-1, -1, 1, 2, -1},
            {-1, -1, 4, -1, 5},
            {-1, 6, 7, -1, -1},
            {-1, -1, 7, -1, -1},
            {-1, -1, 7, -1, -1},
            {-1, -1, 7, -1, -1}
    };

    int state = 0;

    public boolean isNumber(String s) {
        if (s == null && s.equals(" ")) {
            return false;
        }
        s = s.trim();

        for (int i = 0; i < s.length(); ++i) {
            int type = INVALID;
            if (s.charAt(i) == '+' || s.charAt(i) == '-') {
                type = SIGN;
            } else if (Character.isDigit(s.charAt(i))) {
                type = DIGIT;
            } else if (s.charAt(i) == '.') {
                type = DOT;
            } else if (s.charAt(i) == 'e' || s.charAt(i) == 'E') {
                type = EXP;
            }
            state = transitionTable[state][type];
            System.out.println(state);
            if (state == -1) return false;
        }
        return state == 1 || state == 4 || state == 7;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值