Question: Please implement a function to determine whether a string represents a value (including integers and decimals). For example, the strings "+100", "5e2", "-123", "3.1416", "-1E-16", and "0123" all represent numerical values, but "12e", "1a3.14", "1.2. 3", "±5" and "12e+5.4" are not.
Solution: Design an automata state transition algorithm. Starting from a starting state, state transitions will occur when numbers, symbols, e, and E are encountered in different states. We need to check the state after the transition. There are two check results , Accept the state, then continue the state transition until the string is completely traversed; choose to return true or false according to the state at the end; if reject the state, return false directly
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
class Solution {
/*
* 构造状态转移表:
* 对于String[]的下标:
* 0->表示当前位置是数,1->表示当前位置是".",2->表示当前位置是"e"或"E"
* 3->表示当前位置是"-",4->表示当前位置是"+"
* Int1:e之前的数的整数部分,Int2:e之后的数(不能是小数)
* float1:e之前的数的小数部分
* "+":数组最前面的“+”,"++":e后面的“+”(“-”同理)
* "..":"+"或"-"后面的"."(表示整数部分省略的浮点数),".":表示正常浮点数的”.“
* "e":表示数字中的“e”(科学计数法标识)
* "end":表示状态拒绝
*/
private final static Map<String,String[]> map=new HashMap<String,String[]>(){
{
put("+",new String[]{
"Int1","..","end","end","end"});
put("++",new String[]{
"Int2","end","end","end","end"});
put("-",new String[]{
"Int1","..","end","end","end"});
put("--",new String[]{
"Int2","end","end","end","end"});
put(".",new String[]{
"float1","end","e","end","end"});
put("..",new String[]{
"float1","end","end","end","end"});
put("e",new String[]{
"Int2","end","end","++","--"});
put("Int1",new String[]{
"Int1",".","e","end","end"});
put("Int2",new String[]{
"Int2","end","end","end","end"});
put("float1",new String[]{
"float1","end","e","end","end"});
}};
//进行状态转移的函数
private int conditionMove(char target){
if(isDigit(target))
return 0;
else if(target=='.')
return 1;
else if(target=='e'||target=='E')
return 2;
else if(target=='+')
return 3;
else if(target=='-')
return 4;
else
return -1;
}
private boolean isDigit(char arg){
return arg-'0'>=0&&arg-'0'<=9;
}
//状态转移完成时,要检查当前的结束状态
private boolean finish(String arg){
String pattern1="Int.*";
String pattern2="float.*";
String pattern3="\\.";
boolean a=Pattern.matches(pattern3,arg);
return Pattern.matches(pattern1,arg)||Pattern.matches(pattern2,arg)||Pattern.matches(pattern3,arg);
}
public boolean isNumber(String s) {
//去除字符串首尾的空格
s=s.trim();
//找到起始状态
if(s.length()==0)
return false;
if(s.length()==1)
return isDigit(s.charAt(0));
String condition="";
if(s.charAt(0)=='+')
condition="+";
else if(s.charAt(0)=='-')
condition="-";
else if(s.charAt(0)=='.')
condition="..";
else if(isDigit(s.charAt(0)))
condition="Int1";
else
return false;
for(int i=1;i<s.length();i++){
char check=s.charAt(i);
if(conditionMove(check)==-1)
return false;
condition=map.get(condition)[conditionMove(check)];
if(condition.equals("end"))
return false;
}
return finish(condition);
}
}
Time complexity: O(n)
Space complexity: O(1)