A clear and concise solution accepted as best submission in C, well-explained


  • 0

    After reading this problem, I strongly felt terrible for the testing cases which might exhaust my brain hunting for them. So first I did some tests in the custom test box and quickly I found out some unusual cases that I might ignore:

    • .1 -> true;
    • 07 -> true;
    • 09 -> true;
    • "3." -> true;
    • 0000 -> true;
    • 10e300 -> true;
    • 10e-300 -> true;
    • 10e+300 -> true;
    • 10000000000.0000 -> true;
    • e -> false;
    • 0e -> false;
    • 0e+ -> false;
    • 6ee9 -> false;
    • ..2 -> false;
    • ++2 -> false;
    • "-" -> false;
    • "+" -> false;
    • " " -> false;
    • "." -> false;
    • e3 -> false;
    • "3e 3" -> false;
    • 10E20 -> false;
    • 0xf and 0xF -> false;

    So I then swiftly shrink the searching range from (hexadecimal, octal and decimal) to (decimal and its scientific format with some exceptions: ".2" -> true, "09" -> true, "10E10" -> false, " " -> false and so on;

    Now let's just check the code, quite simple and intuitive:

    there will be specific comments to erase some burden for your understanding ^^


    bool isSign(char c)
    {
        return c=='+' || c=='-';
    }
    //AC - 9ms;
    bool isNumber(char* s)
    {
        int index = 0;
        int len = strlen(s);
        int i = 0;
        while(s[i] == ' ') i++; //remove the prefixing white spaces;
        if(isSign(s[i])) i++; //if there is a sign in the head, remove it first;
        while(i < len)
                s[index++] = s[i++];
        while(s[index-1] == ' ') index--; //remove the suffixing white spaces;
        s[index] = '\0';//no prefixing and suffixing white spaces and preceding sign;
        if(index==0) return false; //nothing here;
        bool eOccurred = false;
        bool signOccurred = false;
        bool digitOccurred = false;
        bool dotOccurred = false;
        for(int i = 0; i < index; i++)
        {
            if(isdigit(s[i]))
                digitOccurred = true;
            else if(s[i]=='e')
            {
                if(eOccurred) return false; //e can only appear once;
                if(!digitOccurred) return false; //e is in the first place?! No way!
                if(s[i+1] == '\0') return false; //after e, there is no more character? Impossible!
                eOccurred = true;
            }
            else if(isSign(s[i]))
            {
                if(!eOccurred) return false; //we have remove the preceding sign, so the sign here should be after e only;
                if(signOccurred) return false; //can only appear once;
                if(i==0 || s[i-1]!='e' || s[i+1]=='\0') return false; //after removing the preceding sign, the sign cannot be in the first position; the previous character must be e; and there must be more characters after sign;
                signOccurred = true;
            }
            else if(s[i] == '.')
            {
                if(eOccurred) return false; //dot cannot be after e; no decimals after e only integers;
                if(dotOccurred) return false; //only appear once;
                if(!digitOccurred && s[i+1]=='\0') return false; //no preceding digits and no suffixing digits? No way!
                dotOccurred = true;
            }
            else //white space or other characters;
                return false;
        }
        return true;
    }
    

    There is an organised version for performance and conciseness


    bool isSign(char c)
    {
        return c=='+' || c=='-';
    }
    
    bool isNumber(char* s)
    {
        int index = 0;
        int len = strlen(s);
        int i = 0;
        while(s[i] == ' ') i++; //remove the prefixing white spaces;
        if(isSign(s[i])) i++; //if there is a sign in the head, remove it first - only remove the first ignoring the latter ones if there are some;
        while(i < len)
                s[index++] = s[i++];
        while(s[index-1] == ' ') index--; //remove the suffixing white spaces;
        s[index] = '\0';//no prefixing and suffixing white spaces and preceding sign;
        if(index==0) return false; //nothing here;
        bool eOccurred = false;
        bool signOccurred = false;
        bool digitOccurred = false;
        bool dotOccurred = false;
        for(int i = 0; i < index; i++) //traversing and checking each character;
        {
            if(isdigit(s[i]))
                digitOccurred = true;
            else if(s[i]=='e') //e only appears once; e cannot be the first and the last also;
            {
                if(eOccurred || !digitOccurred || s[i+1] == '\0') return false;
                eOccurred = true;
            }
            else if(isSign(s[i])) //since we removed the first sign(if there is), the latter sign can only occur after e; can only appear once if ignoring the first preceding one; can not be the first since we have remove one if there is; the previous character must be e; and it cannot be the last;
            {
                if(!eOccurred || signOccurred || (i==0 || s[i-1]!='e' || s[i+1]=='\0')) return false;
                signOccurred = true;
            }
            else if(s[i] == '.') //dot cannot be following e; can only appear once; there must be some preceding digits if dot is the last;
            {
                if(eOccurred || dotOccurred || (!digitOccurred && s[i+1]=='\0')) return false;
                dotOccurred = true;
            }
            else //white space or other characters;
                return false;
        }
        return true;
    }

Log in to reply
 

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