参考自:《剑指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 NumericString {
private static int currentIndex;
public static void main(String[] args) {
//true
String str1 = "123.45e+6";
System.out.println(isNumeric(str1.toCharArray()));
//false
String str2 = "1a3.14";
System.out.println(isNumeric(str2.toCharArray()));
//true
String str3 = "+100";
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 the chars
* @return boolean
*/
private static boolean isSignedInteger(char[] chars) {
boolean isSign = currentIndex < chars.length && (chars[currentIndex] == '+' || chars[currentIndex] == '-');
if (isSign) {
currentIndex++;
}
return isUnsignedInteger(chars);
}
/**
* 是否是无符号整数
*
* @param chars the chars
* @return boolean
*/
private static boolean isUnsignedInteger(char[] chars) {
int before = currentIndex;
while (currentIndex < chars.length && chars[currentIndex] >= '0' && chars[currentIndex] <= '9') {
currentIndex++;
}
//至少存在一个数字
return currentIndex > before;
}
}