boolean pointSeen = false;//是否出现过小数点“.”
boolean eSeen =alse;//是否出现过指数标志“e”
boolean numberSeen = false;//是否出现过数字
boolean numberAfterE = true;//e后面是否有数字
注意:字符串和模式串是每个字符依次比较的。而且要弄懂 . 和 * 的意思。
/**
* if else 实现
*
* 思路:首先,搞清楚组成数字的4个部分:
1.数字本身 0-9
2.数字符号 + 或 -
3.小数点 .
4.e或E
然后,判断每一个数字位.判断时需要考虑3种情况:
1.若是正负号,必须出现在首位或e的后一位
2.若是e,之前必须出现过数字且没出现过e
3.若是.,之前必须没出现过.和e
最后,需要设置4个标识位:
* boolean pointSeen = false;//是否出现过小数点“.”
* boolean eSeen =alse;//是否出现过指数标志“e”
* boolean numberSeen = false;//是否出现过数字
* boolean numberAfterE = true;//e后面是否有数字
* @param s
* @return
*/
public static boolean isNumeric2(char[] s) {
if (s == null || s.length == 0)
return false;
// 记录是否出现过数字
boolean numberSeen = false;
// 是否出现过小数点
boolean pointSeen = false;
// 是否出现过指数标志e
boolean eSeen = false;
// e后是否出现过数字
boolean numberAfterE = false;
for (int i = 0; i < s.length; i++) {
char c = s[i];
// 如果是数字
if (c >= '0' && c <= '9') {
numberSeen = true;
numberAfterE = true;//对于输入为纯数字的情况,要先设为true
// 如果是小数点
} else if (c == '.') {
if (pointSeen || eSeen)
return false;
pointSeen = true;
// 如果是e || E,必须没有出现过且出现过数字
} else if (c == 'e' || c == 'E') {
if (eSeen || !numberSeen)
return false;
eSeen = true;
numberAfterE = false;
// 如果出现正负号,必须是首位,或者前一位是e || E
} else if (c == '+' || c == '-') {
if (i != 0 && s[i - 1] != 'e' && s[i - 1] != 'E')
return false;
} else
return false;
}
return numberSeen && numberAfterE;
}
package com.algorithm.str;
/**
* 自动机实现表示数值的字符串 组成部分:空格、符号、数字、点、指数
*
* @author wxq
*
*/
public class AC2 {
enum InputType {
START, // 0
SPACE, // 1
SIGN, // 2
DIGIT, // 3
DOT, // 4
EXPONENT // 5
// NUM_INPUTS // 6
};
//定义状态迁移表, 不画图理解有点困难
//状态迁移表矩阵:每一行为当前状态的下一状态的多种取值
private static int transitionTable[][] ={
//start SPACE SIGN DIGIT DOT E
{-1, 0, 3, 1, 2, -1}, // next states for state 0
{-1, 8, -1, 1, 4, 5}, // next states for state 1
{-1, -1, -1, 4, -1, -1}, // next states for state 2
{-1, -1, -1, 1, 2, -1}, // next states for state 3
{-1, 8, -1, 4, -1, 5}, // next states for state 4
{-1, -1, 6, 7, -1, -1}, // next states for state 5
{-1, -1, -1, 7, -1, -1}, // next states for state 6
{-1, 8, -1, 7, -1, -1}, // next states for state 7
{-1, 8, -1, -1, -1, -1}, // next states for state 8
};
/**
* 有限状态自动机实现
*
* @param string
* @return
*/
static boolean isNumeric(char[] string) {
int state = 0;
for(int i = 0; i < string.length; i++){
char c = string[i];
InputType inputType = InputType.START;//设置初始值
//如果输入字符为空格
if(" ".equals(c)){
inputType = InputType.SPACE;
}
//如果输入字符为+-号
else if(c == '+' || c == '-'){
inputType = InputType.SIGN;
}
//如果输入字符为数字
else if(c >= '0' && c <= '9'){
inputType = InputType.DIGIT;
}
//如果输入字符为点
else if(c == '.'){
inputType = InputType.DOT;
}
//如果输入字符为e E
else if(c == 'e' || c == 'E'){
inputType = InputType.EXPONENT;
}
state = transitionTable[state][inputType.ordinal()];
if (state == -1) return false;
}
return state == 1 || state == 4 || state == 7 || state == 8;
}
public static void main(String[] args) throws InterruptedException {
// String num = "-1e-16";
String num = ".8";
// long start = System.currentTimeMillis();
// Thread.sleep(1);
System.out.println(isNumeric(num.toCharArray()));
// System.out.println("执行时长:"+(System.currentTimeMillis() -
// start)+" ms");
}
}
参考 - 1
参考 - 2
参考 - 3
参考 - 4