参考自:《剑指Offer——名企面试官精讲典型编程题》
题目:表示数值的字符串
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串“+100”、“5e2”、“-123”、“3.1416”及“-1E-16”都表示数值,但“12e”、“1a3.14”、“1.2.3”、“+-5”及“12e+5.4”都不是。
主要思路:表示数值的字符串遵循模式A[.[B]][e|E(C)]或者.B[e|E(C)],其中A为数值的整数部分,B为小数部分,C为’e’或’E’的指数部分。A和B中至少有一个;若字符串中有’e’或’E’,则C为必需的;A和C可带正负号,B不能带正负号。
关键点:数值的字符串模式
时间复杂度:O(n)
public class StringIsNumberic
{
private static int currentIndex;
public static void main(String[] args)
{
String str1 = "123.45e+6"; //true
System.out.println(isNumeric(str1.toCharArray()));
String str2 = "1a3.14"; //false
System.out.println(isNumeric(str2.toCharArray()));
String str3 = "100"; //false
System.out.println(isNumeric(str3.toCharArray()));
}
private static boolean isNumeric(char[] str)
{
if (str == null || str.length == 0) return false;
currentIndex = 0;
//判断整数部分
boolean isNumber = isSignedInteger(str);
//判断小数部分
if (currentIndex < str.length && str[currentIndex] == '.')
{
currentIndex++;
//小数点前后至少有一个是整数就行 注意||的前后位置,短路或
isNumber = isUnsignedInteger(str) || isNumber;
}
//判断指数部分
if (currentIndex < str.length && (str[currentIndex] == 'e' || str[currentIndex] == 'E'))
{
currentIndex++;
//e或E前后都要有整数
isNumber = isNumber && isSignedInteger(str);
}
return isNumber && (currentIndex == str.length);
}
/**
* 是否是有符号整数
*
* @param chars
* @return
*/
private static boolean isSignedInteger(char[] chars)
{
if (currentIndex < chars.length && (chars[currentIndex] == '+' || chars[currentIndex] == '-'))
currentIndex++;
return isUnsignedInteger(chars);
}
/**
* 是否是无符号整数
*
* @param chars
* @return
*/
private static boolean isUnsignedInteger(char[] chars)
{
int before = currentIndex;
while (currentIndex < chars.length &&
chars[currentIndex] >= '0' && chars[currentIndex] <= '9')
{
currentIndex++;
}
return currentIndex > before; //至少存在一个数字
}
}