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
来源:oschina
链接:https://my.oschina.net/u/1425762/blog/508488