zoukankan      html  css  js  c++  java
  • 29. Divide Two Integers

     
        /*
         * 29. Divide Two Integers
         * 2016-4-17 by Mingyang
         * 这个我们就得使用位运算。我们知道任何一个整数可以表示成以2的幂为底的一组基的线性组合,
         * 即num=a_0*2^0+a_1*2^1+a_2*2^2+...+a_n*2^n。
         * 基于以上这个公式以及左移一位相当于乘以2,我们先让除数左移直到大于被除数之前得到一个最大的基。
         * 然后接下来我们每次尝试减去这个基,如果可以则结果增加加2^k,然后基继续右移迭代,直到基为0为止。
         * 因为这个方法的迭代次数是按2的幂直到超过结果,
         * 所以时间复杂度为O(logn)
         * int的绝对值,int里面有一个特殊的数字:-2147483648,它的绝对值或者相反数 2147483648是超出int的范围的,
         * 对于这一情况需要特殊处理。所以不能直接调用 divide(-dividend, divisor)或者divide(dividend, – divisor)。
         * 也不能写 int dv = abs(dividend)。处理方式是使用long long来保存其绝对值
         * 计算绝对值的时候要写 long long dv = abs((long long)dividens)的原因是,
         * abs()有两个重载版本,其中一个是abs(int),另外一个是abs(long),如果不进行显式转换,
         * 则调用abs(int),对-2147483648的返回结果仍是-2147483648
         * 计算两个整数商的时候,有两种选择:将被除数dv右移或者将除数ds右移,循环终止条件是dv < ds。
         * 以上代码选用了右移被除数dv。原因是:当dv最高位(除符号位外)为1时,
         * 左移ds可能因为小于dv而将ds的有效位从最左移出,既会使比较出错,也可能导致死循环。
         * 最后,在return res这里,还是可能会出错的,但是就不在这段程序的考虑范围了,错误输入: -2147483648, -
         */
        public int divide(int dividend, int divisor) {
            //handle special cases
            if(divisor==0) return Integer.MAX_VALUE;
            if(divisor==-1 && dividend == Integer.MIN_VALUE)
                return Integer.MAX_VALUE; 
            //get positive values
            long pDividend = Math.abs((long)dividend);
            long pDivisor = Math.abs((long)divisor); 
            int result = 0;
            while(pDividend>=pDivisor){
                //calculate number of left shifts
                int numShift = 0;    
                while(pDividend>=(pDivisor<<numShift)){
                    numShift++;
                }     
                //dividend minus the largest shifted divisor
                result += 1<<(numShift-1);//这里用加,因为下面减去了曾经计算过的部分,所以用加
                //至于为什么要用1往左移?因为假设两个是倍数关系,96处于3的话,3左移5位到96,那么结果也是1左移5位
                pDividend -= (pDivisor<<(numShift-1));
            }     
            if((dividend>0 && divisor>0) || (dividend<0 && divisor<0)){
                return result;
            }else{
                return -result;
            }
        }
        /*
         *  这道题目也可以不用位运算
         *  见一下大神的算法
         *  每次减去那个数,然后减去以后除数乘以2,结果也乘以2.
         */
         public int divide1(int dividend, int divisor) {
                long  mul=1;long  count=0;
                Boolean neg=false;
                if(((dividend>0)&&(divisor<0))||((dividend<0)&&(divisor>0)))
                 neg=true;
                long a=Math.abs((long)dividend),b=Math.abs((long)divisor);
                long ori=b;
                while(a>=ori)
                {
                     a=a-b;
                     count+=mul;
                     b=b<<1;
                     mul=mul<<1;
                    if(a<b){
                        b=ori;
                        mul=1;
                    }
                }
                if(neg)
                 count*=-1;
                if(count>Integer.MAX_VALUE||count<Integer.MIN_VALUE)
                 return Integer.MAX_VALUE;
                else
                 return (int)count;
            }
  • 相关阅读:
    HDU5446 Unknown Treasure
    C语言课设——通讯录操作系统
    判断设备是否横屏
    禁止用户横屏
    用javascript编写ps脚本
    用户鼠标指针的样式
    如何使用typescript开发node(自动编译,自动重启)
    CSS3:box-sizing:不再为匣子模型而烦恼
    命令行开启自动编译scss(webstrom可开启自动编译)
    TypeError: Cannot read property 'replace' of undefined ----angular2
  • 原文地址:https://www.cnblogs.com/zmyvszk/p/5403071.html
Copyright © 2011-2022 走看看