題目
請實現一個函數用來判斷字符串是否表示數值(包括整數和小數)。例如,字符串"+100"、“5e2”、"-123"、“3.1416”、“0123"都表示數值,但"12e”、“1a3.14”、“1.2.3”、“±5”、"-1E-16"及"12e+5.4"都不是。
解題思路
數值的字符串遵循模式:A[.[B]][eC] 或者 .B[eC],其中 A 表示數值的整數部分,B 緊跟着小數點爲數值的小數部分,C緊跟着 ‘e’ 爲數值的指數部分。A 和 C 可能都是以 ‘+’ 或者 ‘-’ 開頭的數字串,而 B 前面不能有正負號。
在小數裏,可能沒有數值的整數部分,例如小數 .123 等於 0.123,因此整數部分 A 不是必須的。如果一個數沒有整數部分,那麼它的小數部分不能爲空。
判斷一個字符串是否符合上述模式時,首先儘可能地掃描 0~9 的數位(可能包含正負號),也就是 A 部分。如果遇到小數點,則開始掃描 B 部分。如果遇到 ‘e’,則開始掃描 C 部分。
代碼
class Solution {
public boolean isNumber(String s) {
// 先去除字符串首尾兩端空格
String str = s.trim();
if(str.length()==0){
return false;
}
boolean flag = false;
int n = str.length();
// 一、先掃描整數部分
int i = 0;
int a = 0;
if(str.charAt(i) == '+' || str.charAt(i) == '-'){
i++;
}
a = i;
while(a<n && str.charAt(a)>='0' && str.charAt(a)<='9'){
a++;
}
// 判斷整數部分是否存在
flag = a>i;
int j = a;
int b = a;
// 二、如果出現'.',則接下來是小數部分
if(j<n && str.charAt(j) == '.'){
j++;
b = j;
while(b<n && str.charAt(b)>='0' && str.charAt(b)<='9'){
b++;
}
// 1、小數可以沒有整數部分,這種情況小數點後面必須有數字,例如 .123 等於 0.123
// 2、小數點後面可以沒有數字,這種情況就必須有整數部分,例如 233. 等於 233.0
// 3、小數點前後都有數字,例如 233.123
flag = flag || (b>j);
}
int k = b;
int c = b;
// 三、如果出現'e',則接下來是指數部分
if(k<n && str.charAt(k)=='e'){
k++;
if(k<n && (str.charAt(k) == '+' || str.charAt(k) == '-')){
k++;
}
c = k;
while(c<n && str.charAt(c)>='0' && str.charAt(c)<='9'){
c++;
}
// 1、'e' 前面沒有數字時,整個字符串不能表示數字,例如 .e1
// 2、'e' 後面沒有整數時,整個字符串不能表示數字,例如 12e、12e+5.4
flag = flag && (c>k);
}
// 判斷是否滿足模式,以及遍歷到字符串末尾
return flag && (c==n);
}
}