Clear Java solution with ifs


  • 166
    B

    All we need is to have a couple of flags so we can process the string in linear time:

    public boolean isNumber(String s) {
        s = s.trim();
        
        boolean pointSeen = false;
        boolean eSeen = false;
        boolean numberSeen = false;
        boolean numberAfterE = true;
        for(int i=0; i<s.length(); i++) {
            if('0' <= s.charAt(i) && s.charAt(i) <= '9') {
                numberSeen = true;
                numberAfterE = true;
            } else if(s.charAt(i) == '.') {
                if(eSeen || pointSeen) {
                    return false;
                }
                pointSeen = true;
            } else if(s.charAt(i) == 'e') {
                if(eSeen || !numberSeen) {
                    return false;
                }
                numberAfterE = false;
                eSeen = true;
            } else if(s.charAt(i) == '-' || s.charAt(i) == '+') {
                if(i != 0 && s.charAt(i-1) != 'e') {
                    return false;
                }
            } else {
                return false;
            }
        }
        
        return numberSeen && numberAfterE;
    }
    

    We start with trimming.

    • If we see [0-9] we reset the number flags.
    • We can only see . if we didn't see e or ..
    • We can only see e if we didn't see e but we did see a number. We reset numberAfterE flag.
    • We can only see + and - in the beginning and after an e
    • any other character break the validation.

    At the and it is only valid if there was at least 1 number and if we did see an e then a number after it as well.

    So basically the number should match this regular expression:

    [-+]?(([0-9]+(.[0-9]*)?)|.[0-9]+)(e[-+]?[0-9]+)?


  • 0
    Y
    This post is deleted!

  • 0
    C

    well explained, thank you.


  • 0
    H

    Excellent code! Thank you! (at least 30 characters)


  • 3
    S

    numberAfterE seems to be redundent


  • 1
    B

    Yeah, I guess I could reset numberSeen, and not use numberAfterE all together. Thanks for the suggestion!


  • 0
    K

    Well written code!
    Just a suggestion i guess we can get "String index out of range: -1" for second last condition (checking + and -) and may substitute code with this : first check if i isn't out of index
    else if(s.charAt(i)=='+' || s.charAt(i)=='-'){
    if(i!=0){
    if(s.charAt(i-1)!='e'){
    return false;
    }
    }
    }


  • 0
    B

    @Khushbu27 thanks, but that is not needed. If the first term is false in an AND expression there is no need to evaluate the second one, so there will be no exception there. ;)


  • 0
    K

    Yes agreed ;) sorry i didn't scan through that part right ;)


  • 0
    K

    Also do you think it would work for '++' ?


  • 1
    H

    Thank you. Do you think when you check the '.', you should make sure there is number before '.'?

    I think the code should be
    if(s.charAt(i) == '.') {
    if(eSeen || pointSeen || !numberSeen) {
    return false;
    }
    }


  • 0
    B

    @Khushbu27 nope, because the +/- must be at the beginning, or after an e


  • 0
    B

    @Hao198754 Nope, because .5 is a valid number which is 0.5


  • 0
    W

    The regular expression doesn't cover '3.' which is valid, I think it should be [-+]?(([0-9]+(.[0-9]*)?)|.[0-9]+)(e[-+]?[0-9]+)?


  • 0
    B

    @wanghp18 you are right, I wasn't focusing that much to get the correct regex, but definitely you are right ;)


  • 1
    D

    how did you come up this amazing solution?


  • 1
    B

    @wanghp18 I think the regex should be [-+]?(([0-9]+(\\.[0-9]*)?)|\\.[0-9]+)(e[-+]?[0-9]+)?


  • 0
    H

    what if the number is 2.334E2.0


  • 0
    B

    @huyucheng100 well, that is not a "valid" number in scientific notation. The exponent must be an integer.


  • 0
    L

    Beatiful code,thank you!

    At first time, I write this code, but BigDecimal can't be used. :-D

    public boolean isNumber(String s) {
            try {
                new BigDecimal(s);
            } catch (Exception e) {
                return false;
            }
            return true;
        }
    

Log in to reply
 

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