Monday, October 7, 2013

Valid Number

Q:
Validate if a given string is numeric.
Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

A:
这道题,就是被逼上梁山,  当008 也可以返回true的时候, 我们就不需要分2,8,16,10 进制了。 操蛋啊~~~~~~~~~

public class Solution {
    public boolean isNumber(String s) {
        // 1) all digits , int , 10 based, integer
        // 2) hextercal, start from 0X or 0x
        // 3) octcal, start from 0
        // 4) what the hell.     binary number   int a = 0b11  , which equals to 3 in tens base

        // for doubles ,
        // 4)exist '.' , and may have L(l) or D(d) at tail
        // 4.5: be careful about the case of 1. and .2 both are valid number
        // 5) E(e) case, eg. 3e-4 ( before e, there must be digits, and after E,
        // it must be integer(also have have)
        s = s.trim(); // delete the white space at two ends
        if (s.length() == 0) 
            return false;
        s = s.toUpperCase();
        
        // check start of the string, to see whether it is hextercal or octcal
        boolean isInteger = checkInt(s,true) || checkHex(s) ||checkBinary(s) || checkOct(s);
        boolean isDouble = checkDouble(s) || checkE(s);
        return isInteger || isDouble;
    }

    private boolean checkBinary(String s) {
        // check whether s is the binary string
        if(s.length() <=2)
            return false;
        
        // check the first two chars
        if(!(s.charAt(0) == 0) && s.charAt(1)=='B')
            return false;
        
        // check the rest
        for(int i =2;i<s.length();i++){
            char ch = s.charAt(i );
            if(ch!='1' || ch !='0')
                return false;
        }
        return true;        
    }

    private boolean checkE(String str) {
        // when b == true, the front part must be integer, else it could be
        // doulbe
        // isCoefficientInt is the flag, to check whether the coefficient is
        // integer or double
        int eIndex = str.indexOf('E'); // as str is in upper case
        // do not exist E   , or is the first or last  position
        if (eIndex <= 0 || eIndex == str.length() - 1) 
            return false;
        else 
            return (checkInt(str.substring(0, eIndex),true) || checkDouble(str
                    .substring(0, eIndex)))
                    && checkInt(str.substring(eIndex + 1),true);
    }

    private boolean checkDouble(String str) {
        // must exist '.' , and also, must
        if (str.charAt(0) == '-' || str.charAt(0) =='+')  // having negative sign
            str = new StringBuffer(str).deleteCharAt(0).toString();
        
        int dotIndex = str.indexOf('.');        
        if (dotIndex < 0) { // do not exist dot '.'
            return false;
        } else if (dotIndex == 0) { // .1 is also a valid number
            return checkInt(str.substring(1),false);
        } else if (dotIndex == str.length() - 1) {
            return checkInt(str.substring(0, dotIndex),true);
        } else {
            return checkInt(str.substring(0, dotIndex),false)
                    && checkInt(str.substring(dotIndex + 1),false);
        }
    }

    private boolean checkOct(String str) {
        if (str.length() <= 1 || str.charAt(0) != '0') 
            return false;
        // now str begin with 0 
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if(ch == '.')continue;
            if (!(ch >= '0' && ch <= '7')) 
                return false;
        }
        //check the digital case
        return checkInt(str.substring(1),true) || checkDouble(str.substring(1));
    }

    private boolean checkInt(String str, boolean isAllowSign) {
        // if isAllowSign == true, we allow the existing of '-'  or '+' signs
        // otherwise 
        // check whether is itinteger number 0 -- 9
        if (str.length() == 0)
            return false;
        if(isAllowSign){
            if (str.charAt(0) == '-' || str.charAt(0) =='+') { // having negative sign
                str = new StringBuffer(str).deleteCharAt(0).toString();
            }
        }
        if (str.length() == 0)
            return false;
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (!(ch >= '0' && ch <= '9')) 
                return false;
        }
        return true;
    }

    private boolean checkHex(String str) {
        // check whether is it hexercal number (0X or 0x has been removed)
        if (str.length() <= 2) 
            return false;
        
        if (!(str.charAt(0) == '0' && str.charAt(1) == 'X')) 
            return false;
        
        str = str.substring(2);
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            boolean isHex = (ch >= '0' && ch <= '9')
                    || (ch >= 'A' && ch <= 'F');
            if (isHex == false) 
                return false;
        }
        return true;
    }
}





Mistakes:
1: “abc” checkInt() 竟然能通过为true,  在检验时, 用了( ch<'0' && ch >'9' )   这个 永远不会为true的,哈哈。   后来,改成了,中规中矩的
           if (! (ch >=  '0' && ch <= '9')) {
                return false;
            }
2: 当isCoeffienctInt为false的时候, 我们在检查E前面的时候,  要test both int and doulbe case

3: 这个是题意理解不清楚, 当input 为“”的时候,我们应该返回false, 而不是true
4:  题意理解不对, “.1” 的时候, 也是允许的。
    同样,        “3.”   也是被允许的。
5:  checkBinary () 中,应该是检测 ch != '1'   ||    ch != '0'   是 or    而不是  and 的关系。  日球~~~
6:  前面不仅仅是 -    , 也可以是 +   号。
7: 在checkInt()中 check 正负号的时候, 要先后检查,是否str 为空了。╮(╯▽╰)╭
8: checkDouble的时候,还是先抽取前面的符号吧, 否则,不方便检测“ +.2" 的情况。

9: ??????  008 在java里面是不被允许的,为什么在这里,可以呢???
10:   ".00" 是可以的,为什么呢??? 那么, ”000“可以吗?
11:  07L 是false      01 是true,  为什么呢?????
12:  “01.” 到底算什么????就是不管八进制了?

Learned:
1:   s.trim(); 返回的是s的一个copy,  而不是在s身上直接做的操作。
2:  int a = 0010;      这里, a == 8 是被允许的。
3:  八进制,也可以有double 类型 。  但是 16进制 没有。  what the fuck,   这都什么事儿啊~~~~
System.out.println(03.0);           ------------正确
System.out.println(0X3.0); ---------  compile error

4: System.out.println(1e2);和System.out.println(0x1e2);是有区别的,
第一个是科学计数法 结果是100
而第二个是十六进制的数字 ,不再是科学计数法了 结果是 1*16*16+14*16+2=482
   十六进制中 a代表10,b代表11。。e代表14

No comments:

Post a Comment