1. 程式人生 > 實用技巧 >兩行css程式碼實現瀑布流:html,css最簡單的瀑布流實現方式

兩行css程式碼實現瀑布流:html,css最簡單的瀑布流實現方式


這題完美的詮釋了什麼叫“面向測試用例程式設計”。由於要考慮的情況很多,所以基本的思路是先根據給出的測試用例寫出規則判斷無效的情況,然後再根據提交的錯誤對剩下的情況進行特判,如果不滿足所有“無效的情況”,則有效。題目特別提了“我們有意將問題陳述地比較模糊”,這個“有意地陳述地模糊”就很靈性,所以一開始很難考慮到所有情況,WA幾次就知道有哪些測試用例(規則)了。
先從題目給出的測試用例裡總結幾點規則:

  1. 給出的字串可能會包含字首和字尾的空格,需要先去掉字首和字尾的空格;
  2. 有可能字串是一個科學計數法的數字,因此會出現字元'e'或'E',但'e'(或'E')只能出現一次,且不能出現在字串的開頭和結尾位置;
  3. 'e'(或'E')的後面可能緊跟一個'+'或'-',正負號只能出現在兩個地方,一是字串開頭,二就是'e'(或'E')的後面,其他位置如果出現正負號,就可以判定為無效! 另外,'e'(或'E')後面如果出現了正負號,後面還必須有數字,所以要判斷正負號是不是字串的結尾,如果是,也可以判定為無效;
  4. 字串開頭可以是正負號,但如果只有正負號,則無效;
    再從提交的測試用例裡總結幾點規則:
  5. 字串可以由'.'開頭,比如".1"就表示0.1,這種'.'後面是數字的就是合法的,'.'後面跟著其他字元就是非法的;
  6. '.'和'e'只能分別出現一次,多於一次就是無效的
class Solution {
public:
    bool isNumber(string s) {
        int left = 0, right = s.size() - 1;                  //分別從左右過濾掉字首和字尾的空格
        while(left <= right && s[left] == ' ') {
            ++left;
        }
        while(left <= right && s[right] == ' ') {
            --right;
        }
        if(left > right) {                                    //如果字串只有空格組成,則無效
            return false;
        }
        s = s.substr(left, right - left + 1);                 //留下刪除掉字首和字尾的空格之後的字串
        if(s[0] == '+' || s[0] == '-') {                      //如果字串由正負號開頭,則刪掉開頭的字串再作判斷
            s = s.substr(1);                                  //substr只傳入一個引數1,表示留下從第一個位置到末尾的子串(即刪除第0個位置的正負號)
        }
        if(s.empty()) {                                       //如果刪掉正負號之後字串為空,則無效
            return false;
        }
        if(s[0] == '.' && (s.size() == 1 || s[1] == 'e' || s[1] == 'E')) {    //如果字串有'.'開頭,則有三種情況是無效的:(1)字串只有一個字元'.'; (2)下一個字元是'e'; (3)下一個字元是'E'。 實際上,只要'.'後面的字元不是數字就都是無效的,只不過其他情況在別處判斷了。
            return false;
        }
        int dotNum = 0, eNum = 0;                  //記錄'.'和'e'(或'E')的數量
        for(int i = 0; i < s.size(); ++i) {
            if(s[i] == '.') {                      
                if(dotNum > 0 || eNum > 0) {       //如果'.'出現次數大於1或者'.'在'e'(或'E')之後出現,則無效
                    return false;
                } else {
                    ++dotNum;
                }
            } else if(s[i] == 'e' || s[i] == 'E') {            
                if(i == 0 || i == s.size() - 1 || eNum > 0) {      //如果'e'(或'E')出現在開頭或者結尾位置,或者出現次數大於1,則無效
                    return false;
                } else if(s[i + 1] == '+' || s[i + 1] == '-') {     //如果'e'(或'E')後面的字元是正負號,需要特判
                    if(i + 1 == s.size() - 1) {                     //正負號後面需要有數字,如果正負號已經是最後一個字元了(後面啥都沒),則無效
                        return false;
                    } else {
                        ++i;                                        //如果正負號後面還有東西,我們就跳過正負號,繼續判斷後面的
                    }
                }
                ++eNum;
            } else if(!(s[i] >= '0' && s[i] <= '9')) {              //其他情況的字元只能是數字,其他都是無效的
                return false;
            }
        }
        return true;                                                //如果不滿足上述任何情況,我們就認為字串可以表示為一個有效的數字!
    }
};

複雜度分析:由於只遍歷一遍字串,時間複雜度是O(n);只開了常數個變數,空間複雜度是O(1)。