LeetCode:Valid Number - 判断字符串中内容是否为数字

原创
2015/09/19 13:51
阅读数 1.7K

1、题目名称

Valid Number(判断字符串中内容是否为数字)

2、题目地址

https://leetcode.com/problems/valid-number/

3、题目内容

英文:Validate if a given string is numeric.

中文:给出一个字符串,检查这个字符串中内容是否是一个数字

例如:“0”、“ 0.1”、“2e10”是数字,“abc”、“1 a”不是数字

4、解题方法1

使用正则表达式检查字符串是一个比较好的方法,正则表达式的结构如下图所示:

对应的正则表达式为:^([+-])?((\d+)(\.)?(\d+)?|(\d+)?(\.)?(\d+))(e([+-])?(\d+))?$

Java代码如下,注意为了让编译器不把字符“\”识别为转义字符,须将“\”转换为“\\”使用。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 功能说明:LeetCode 65 - Valid Number
 * 开发人员:Tsybius2014
 * 开发时间:2015年9月18日
 */
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;
    }
}

5、解题方法2

上面的方法我在OJ上运行花了484ms,虽然代码很清晰,代码长度也控制在很短的范围,但使用时间比较长。如果希望提高速度,可以使用有限状态机来处理这个问题。

状态机各状态图如下:

(其中每个状态接收到额外输入时都会跳转到FAILURE状态)

一段实现此功能的Java代码如下,这段代码在OJ上的效率为316ms。

/**
 * 功能说明:LeetCode 65 - Valid Number
 * 开发人员:Tsybius2014
 * 开发时间:2015年9月19日
 */
public class Solution {
    
    /**
     * 判断指定字符串是否为数字
     * @param s 字符串
     * @return true:是数字 false:不是数字
     */
    public boolean isNumber(String s) {
        
        s = s.trim(); 
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == 'x') {
                return false;
            }
        }
        s = s + 'x'; //x为标记字符串结束的字符
        
        State curState = State.STATE_BEGIN;
        for (int i = 0; i < s.length(); i++) {
            curState = getNextState(curState, s.charAt(i));
            if (curState == State.STATE_SUCCESS) {
                return true;
            } else if (curState == State.STATE_FAILURE) {
                return false;
            }
        }
        
        return false;
    }
    
    //状态枚举
    private enum State {

        //启动
        STATE_BEGIN,
        //正负号
        STATE_SIGN,
        //整数部分
        STATE_NUM_INT,
        //小数点1
        STATE_DOT1,
        //小数点2
        STATE_DOT2,
        //小数部分
        STATE_NUM_DEC,
        //指数符号e
        STATE_E,
        //指数正负号
        STATE_SIGN_E,
        //指数数字
        STATE_NUM_E,
        //正常结束
        STATE_SUCCESS,
        //异常结束
        STATE_FAILURE
        
    };
    
    /**
     * 根据当前字符与当前状态获取下一个状态
     * @param state
     * @param ch
     * @return
     */
    private State getNextState(State state, char ch) {
        
        switch (state) {
        case STATE_BEGIN: 
            return getNextStateBegin(ch);
        case STATE_SIGN:
            return getNextStateSign(ch);
        case STATE_NUM_INT:
            return getNextStateNumInt(ch);
        case STATE_DOT1:
            return getNextStateDot1(ch);
        case STATE_DOT2:
            return getNextStateDot2(ch);
        case STATE_NUM_DEC:
            return getNextStateNumDec(ch);
        case STATE_E:
            return getNextStateE(ch);
        case STATE_SIGN_E:
            return getNextStateSignE(ch);
        case STATE_NUM_E:
            return getNextStateNumE(ch);
        case STATE_SUCCESS:
            return State.STATE_SUCCESS;
        case STATE_FAILURE:
            return State.STATE_FAILURE;
        default:
            break;
        }
        
        return State.STATE_FAILURE;
    }
    
    /**
     * 初始状态
     * @param ch 输入字符
     * @return 下一个状态
     */
    private State getNextStateBegin(char ch) {
        switch (ch) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return State.STATE_NUM_INT;
        case '+':
        case '-':
            return State.STATE_SIGN;
        case '.':
            return State.STATE_DOT1;
        default:
            return State.STATE_FAILURE;
        }
    }

    /**
     * 正负号
     * @param ch 输入字符
     * @return 下一个状态
     */
    private State getNextStateSign(char ch) {
        switch (ch) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return State.STATE_NUM_INT;
        case '.':
            return State.STATE_DOT1;
        default:
            return State.STATE_FAILURE;
        }
    }

    /**
     * 整数部分
     * @param ch 输入字符
     * @return 下一个状态
     */
    private State getNextStateNumInt(char ch) {
        switch (ch) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return State.STATE_NUM_INT;
        case '.':
            return State.STATE_DOT2;
        case 'e':
            return State.STATE_E;
        case 'x':
            return State.STATE_SUCCESS;
        default:
            return State.STATE_FAILURE;
        }
    }

    /**
     * 小数点1
     * @param ch 输入字符
     * @return 下一个状态
     */
    private State getNextStateDot1(char ch) {
        switch (ch) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return State.STATE_NUM_DEC;
        default:
            return State.STATE_FAILURE;
        }
    }

    /**
     * 小数点2
     * @param ch 输入字符
     * @return 下一个状态
     */
    private State getNextStateDot2(char ch) {
        switch (ch) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return State.STATE_NUM_DEC;
        case 'e':
            return State.STATE_E;
        case 'x':
            return State.STATE_SUCCESS;
        default:
            return State.STATE_FAILURE;
        }
    }

    /**
     * 小数部分
     * @param ch 输入字符
     * @return 下一个状态
     */
    private State getNextStateNumDec(char ch) {
        switch (ch) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return State.STATE_NUM_DEC;
        case 'e':
            return State.STATE_E;
        case 'x':
            return State.STATE_SUCCESS;
        default:
            return State.STATE_FAILURE;
        }
    }

    /**
     * 指数符号e
     * @param ch 输入字符
     * @return 下一个状态
     */
    private State getNextStateE(char ch) {
        switch (ch) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return State.STATE_NUM_E;
        case '+':
        case '-':
            return State.STATE_SIGN_E;
        default:
            return State.STATE_FAILURE;
        }
    }

    /**
     * 指数正负号
     * @param ch 输入字符
     * @return 下一个状态
     */
    private State getNextStateSignE(char ch) {
        switch (ch) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return State.STATE_NUM_E;
        default:
            return State.STATE_FAILURE;
        }
    }

    /**
     * 指数数字
     * @param ch 输入字符
     * @return 下一个状态
     */
    private State getNextStateNumE(char ch) {
        switch (ch) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return State.STATE_NUM_E;
        case 'x':
            return State.STATE_SUCCESS;
        default:
            return State.STATE_FAILURE;
        }
    }
}

END

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部