1. 程式人生 > >【LeetCode】65 有效數字

【LeetCode】65 有效數字

驗證給定的字串是否為數字。
例如:
“0” => true
" 0.1 " => true
“abc” => false
“1 a” => false
“2e10” => true
說明: 我們有意將問題陳述地比較模糊。在實現程式碼之前,你應當事先思考所有可能的情況。


解題思路:
這道題的情況十分複雜,需要自己一個一個嘗試某個形式算不算數字,也正因此,這道題斬獲了做這麼多題以來“最低贊/踩比”獎。不過貌似前幾天把踩的數字給隱藏了,我記得當時是453個踩,16個贊…
巨集觀思路:
1 出現在字串裡的字元主要是這麼幾種情況:①數字 ②小數點 ③e ④正負號 ⑤其他字元
2 按順序讀取每個字元,根據每種字元出現的條件來判否,若最後未判否,則判定為數字


這道題的坑:
1 剛開始我做的時候,是根據已出現過的特殊字元(小數點和e)來做的,需要判斷許多種情況;而正確(最快最簡單的)思路是根據當前字元,判斷可以判否的情況。
2 e只能出現一次,且前後必須都有數字
3 小數點只能出現一次,且不能在e後面
4 正負號可以出現在開頭或者e的下一個字元

5 你看我這麼描述可能很清楚,但是很容易把限制條件都放在一處進行判定,比如,1、2條可以這麼說:e只能出現一次,前後必須有數字,且不能在小數點前面;小數點只能出現一次。 如果是這種思路,沒辦法做下去,因為無法判定後方的,很容易陷入對非邊界特例的單獨處理中。
收穫:分析可能出現的情況,根據已出現的內容進行判定。

程式碼:

class Solution {
    public boolean isNumber(String s) {
        s = s.trim();
        
        boolean eSeen = false;
        boolean pointSeen = false;
        boolean numSeen = false;
        boolean numAfterESeen = true;
        
        char[] str = s.toCharArray();
        for(int i = 0;i < str.length;i++){
            if (str[i] >= '0' && str[i] <= '9'){
                numSeen = true;
                numAfterESeen = true;
            }
            else if (str[i] == '.'){
                if (pointSeen || eSeen)
                    return false;
                pointSeen = true;
            }
            else if (str[i] == 'e'){
                if (!numSeen || eSeen)
                    return false;
                eSeen = true;
                numAfterESeen = false;
            }
            else if (str[i] == '+' || str[i] == '-'){
                if(i != 0 && str[i-1] != 'e')
                    return false;
                    
            }
            else return false;
        }
        
        return numSeen && numAfterESeen;
    }
}