C, Recursive


  • 0
    M

    After some trial and error figured out that once we validate the start of the string, then we need to only look for the following 4 conditions:

    1. If it's 'e', then ensure it's the first instance and next character is a number or a sign.
    2. If it's '.', then ensure it's the first instance and it's not preceded by 'e'.
    3. If it's a sign, then preceding character has to be 'e' and the next one has to be a number.
    4. Else if it's an invalid character, (not a number/sign/'e'/'.'/'\0') then return FALSE.
    #define IS_NUM(x)         (((x) >= 48) && ((x) <= 57))
    #define IS_SIGN(x)        (((x) == '-') || ((x) == '+'))
    #define IS_VALID(x)       ((IS_NUM((x))) || (IS_SIGN((x))) ||\
                               ((x) == 'e' || (x) == '.') || (x) == 0)
    
    bool isNum(char* s, int *e, int *dot)
    {
        /* Skip space, if the end is not NULL, then return FALSE */
        while (*s == ' ') { s++;
            if ((*s) && (*s != ' '))
                return FALSE;
        }
        
        /* Filter the four invalid patterns */
       if (((*s == 'e') && ((!IS_NUM(*(s + 1)) && !IS_SIGN(*(s + 1))) || *e)) ||  // 1
            ((*s == '.') && (*e || *dot)) ||                                      // 2
            (IS_SIGN(*s) && ((*(s - 1) != 'e') || !IS_NUM(*(s + 1)))) ||          // 3
            (!IS_VALID(*s)))                                                      // 4
            return FALSE;
    
        /* Track 'e' and '.' characters, there cannot be more than one of these */
        *e = (*s == 'e') ? 1 : *e;
        *dot = (*s == '.') ? 1 : *dot;
    
        /* Unless it is a NULL, move to the next character */
        return (*s == 0) ? 1 : isNum(s + 1, e, dot);
    }
    
    bool isNumber(char* s)
    {
        int e = 0, dot = 0;
    
        /* Skip leading white spaces */
        while (*s == ' ') ++s;
    
        /* Skip the first leading sign */
        if (IS_SIGN(*s)) s++;
    
        /* Leading NULL or 'e' is invalid. So is a '.' which is not followed
           by a number */
        if ((*s == 0) || (*s == 'e') || (*s == '.' && !IS_NUM(*(s + 1))))
            return FALSE;
        return isNum(s, &e, &dot);
    }
    

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.