2017年1月22日 星期日

LeetCode#65 Valid Number

這一題如果沒有用 Regular Expression 先試試看,直接 coding 的人要不是本事高超,要不就是勇氣可佳。

像站長這種小孬孬,還是決定先用 Regular Expression 試水溫。

不過就算是用 Regular Expression,還是費了好一番功夫。直到從 Regular Expression Cookbook 抄了一堆範例才成功,下方為 JavaScript 版源碼:
/**
 * @param {string} s
 * @return {boolean}
 */
var isNumber = function(s) {
    return /^\s*[-+]?([0-9]+(\.[0-9]*)?|\.[0-9]+)([eE][-+]?[0-9]+)?\s*$/.test(s);
};
直接把上方的 JavaScript 翻譯成 C 語言效果如何?
#define IS_SIGN(ch) (ch == '+' || ch == '-')
#define IS_EXP(ch) (tolower(ch) == 'e')

bool isNumber(char* s) {
    int len;
    char *begin, *end;
    
    if(s == 0 || (len = strlen(s)) == 0)
        return false;
    
    begin = s;
    end = s + len - 1;
    while(isspace(*begin))
        ++begin;
    
    while(isspace(*end) && end > begin)
        --end;
    
    if(begin > end)
        return false;
    
    ++end;
    if(IS_SIGN(*begin))
        ++begin;
    
    if(isdigit(*begin)){
        ++begin;
        while(isdigit(*begin))
            ++begin;
        
        if(*begin == '.'){
            ++begin;
            while(isdigit(*begin))
                ++begin;
        }
        
        if(begin >= end){
            return true;
        }else if(IS_EXP(*begin)){
            ++begin;
        }else{
            return false;
        }
        
        if(begin >= end)
            return false;
        
        if(IS_SIGN(*begin))
            ++begin;
        
        if(isdigit(*begin))
            ++begin;
        else
            return false;
            
        while(isdigit(*begin))
            ++begin;
        
        if(begin >= end)
            return true;
        else
            return false;
        
    }else if(*begin == '.'){
        ++begin;
        if(isdigit(*begin))
            ++begin;
        else
            return false;
        
        while(isdigit(*begin))
            ++begin;
        
        if(begin >= end)
            return true;
        else if(IS_EXP(*begin))
            ++begin;
        else
            return false;
        
        if(IS_SIGN(*begin))
            ++begin;
        
        if(isdigit(*begin))
            ++begin;
        else
            return false;
            
        while(isdigit(*begin))
            ++begin;
        
        if(begin >= end)
            return true;
        else
            return false;        
        
    }else{
        return false;
    }
}
這樣也只有第三名,第一名究竟用了什麼妖術?

由這份題解可以發現,http://weibo.com/luangong 用了有限狀態機,所以只需要走訪一次字串即可。還有人用 strtod,那就比 Regular Expression 更像作弊了wwww


沒有留言:

張貼留言