劍指offer之字符串是否爲數值

1. 題目

這是《劍指offer》上的一道題,剛開始以爲這是一道挺簡單的題目,後來發現本身太年輕了,考慮的因素太少了,思考了而是分鐘仍是無從下手,看了做者的思路深深被他折服了,題目以下:java

請實現一個函數用來判斷字符串是否表示數值(包括整數和小數)。例如,字符串 "+100"、"5e2"、"-123"、"3.1415" 以及 "-1E-16" 都表示數值,但"12e"、"1a3.14"、"1.2.3"、"+-5" 以及 "12e+5.4" 都不是git

2. 思路

表示數值的字符串遵循模式 A[.[B]][e|EC] 或者 .B[e|EC],其中 A 爲數值的整數部分,B 緊跟着小數點爲數值的小數部分,C 緊跟着 'e' 或者 'E' 爲數值的指數部分。在消暑利可能沒有數值的整數部分。例如,小數 .123 等於 0.123。所以 A 部分不是必需的。若是一個數沒有整數部分,那麼它的小數部分不能爲空。github

上述 A 和 C 都是可能以 '+' 或者 '-' 開頭的 0~9 的數位串;B 也是 0~9 的數位串,但前面不能有正負號。數組

以表示數值的字符串 "123.45e+6" 爲例,"123" 是它的整數部分 A,"45" 是它的小數部分 B,"+6" 是它的指數部分 C。函數

判斷一個字符串是否符合上述模式,首先應該掃描 0~9 的數位,也就是上面數值中表示整數的 A 部分。若是遇到小數點,則開始掃描數值小數部分 B。若是遇到 'e' 或者 'E',則開始掃描表示數值指數的 C 部分。根據這樣的思路,給出參考代碼:code

public class Main{
    public boolean isNumeric(char[] str){
        if(str==null)
           return false;
        // 這個數組就一個元素,存儲遍歷字符串的下標
        int[] index = {0};
        // 先遍歷字符串的整數部分
        boolean numeric = scanInteger(str,index);
        // 碰到小數點時,開始遍歷 B 部分
        if(index[0]<str.length && str[index[0]]=='.'){
            index[0]++;
            /*
             * 這裏使用 || 的緣由
             * 1. 小數能夠沒有整數,如 .123 等於 0.123
             * 2. 小數點後面能夠沒有數字,如 223. 等於  233.0
             * 3. 固然,小數點前面和後面均可以有數字,如 2233.444
             */
            numeric = scanUnsignedInteger(str,index) || numeric;
        }
        // 若是出現 'e' 或者 'E',開始遍歷指數部分
        if(index[0]<str.length && (str[index[0]]=='e' || str[index[0]]=='E')){
            index[0]++;
            /*
             * 這裏使用 && 的緣由
             * 1. 當 e 或 E 前面沒有數字時,整個字符串不能表示數字,如 .e一、e2。
             * 2. 當 e 或 E 後面沒有整數時,整個字符串不能表示數字,如 23e、23e+5.4
             */
            numeric = numeric && scanInteger(str,index);
        }
        return index[0]==str.length && numeric;
    }
    
    /*
     * 該函數用來掃描字符串中 0~9 的數位(相似於一個無符號整數),能夠用來匹配前面數值
     * 模式中的 B 部分
     */
    private boolean scanInteger(char[] str,int[] index){
        if(index[0]<str.length && (str[index[0]]=='+' || str[index[0]]=='-'))
            index[0]++;
        return scanUnsignedInteger(str,index);
    }
    
    /*
     * 該函數掃描可能以表示正負號的 '+' 或者 '-' 開頭的 0~9 的數位(相似於一個有符號整數)
     * 能夠用來匹配前面數值模式中的 A 和 C 部分。
     */
    private boolean scanUnsignedInteger(char[] str,int[] index){
        int before = index[0];
        while(index[0]<str.length && str[index[0]]>='0' && str[index[0]]<='9')
            index[0]++;
        return index[0]>before;
    }
}

更多《劍指offer》的題目以及源代碼能夠參考個人 github字符串

相關文章
相關標籤/搜索