题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、“5e2”、"-123"、“3.1416”、"-1E-16"、“0123"都表示数值,但"12e”、“1a3.14”、“1.2.3”、"±5"及"12e+5.4"都不是。
题解:设计一个自动机状态转移算法,从一个起点状态开始,在不同状态下遇到数字、符号、e、E会产生状态转移,我们需要对转移后的状态进行状态检查,检查结果有两种,接受状态,则继续进行状态转移,直到字符串完全遍历;根据结束时状态的情况选择返回true或者false;拒绝状态,则直接返回false
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);
}
}
时间复杂度:O(n)
空间复杂度:O(1)