LintCode_两个整数相除

来源:互联网 发布:智能网络推广系统 编辑:程序博客网 时间:2024/05/16 08:38

问题描述:

将两个整数相除,要求不使用乘法、除法和 mod 运算符。如果溢出,返回 2147483647 。

样例:给定被除数 = 100 ,除数 = 9,返回 11

算法思想:

方法一:(这是开始自己想出来的,算法思想简单,缺点是,循环次数多,运行速度慢

如果不能采用乘除运算方法,那么可以采用加减方式,当然还要(1)、注意分类:正正,正负,负正,负负;(2)、溢出问题;

    public static int divide(int dividend, int divisor) {        if(divisor==0){            return 2147483647;        }                if(dividend==0){            return 0;        }                if(dividend==-2147483648&&divisor==-2147483648){            return 1;        }                        int result=0;                //如果被除数为负数,除数为正数        if(dividend<0&&divisor>0){            //循环将除数加至被除数中,直至被除数大于或者等于0            while((dividend+divisor)<=0){                       dividend+=divisor;                result--;            }        }else if(dividend>0&&divisor>0){            //被除数与除数都是正数,直接计算,result++            while((dividend-divisor)>=0){                                dividend-=divisor;                result++;            }                  }else if(dividend>0&&divisor<0){            //被除数为正数,除数为负数,将除数转变成正数,result--            while((dividend+divisor)>=0){                dividend+=divisor;                result--;            }        }else if(dividend<0&&divisor<0){            while((dividend-divisor)<=0&&result<2147483647){                //可能(-2147483648)/(-1)=2147483648,刚好导致溢出                dividend=dividend-divisor;                result++;            }        }        return result;    }    

注:此题在测试过程中,最纠结的就是碰到-2147483648等的溢出问题,例如被除数和除数都是-2147483648时,如果,在最开始没有使用
<pre name="code" class="java" style="color: rgb(113, 113, 113);">        if(dividend==-2147483648&&divisor==-2147483648){            return 1;        }
语句,result最终结果为2147483647。在负负情况下添加添加打印result和dividend的语句,可以看到result和dividend在while循环中的结果,很奇怪;如果被除数和除数是其他数据,运行结果正常。因此,这不是逻辑问题,而是溢出!

方法二:百度了下别人的做法,发现可以使用位运算,减少循环步骤,大大减少了运算时间,在被除数很大,除数很小的时候很有优势。因为左移一位相当于数字乘2;所以有时左移右移运算配合加减法,就相当于乘除法;

    public static  int divide(int dividend, int divisor) {          // Write your code here          //判断dividend与divisor是否是同符号,同符号,结果为正,不同符号,结果为负数        Boolean resultGreatThanZero = true;          if(dividend>0&&divisor<0||dividend<0&&divisor>0)              resultGreatThanZero = false;          //保存最终结果        int ret = 0;        //将d1与d2都转变成正数运算        long d1 = abs((long)dividend);          long d2 = abs((long)divisor);                  while(d1>=d2)          {              long temp = d2;              long cnt = 1;              while(d1>=temp)              {                  d1-=temp;                  ret+=cnt;                //左移一位,相当于cnt乘2;                //不能直接使用乘法运算,那么可以采用左移代表乘法,可以减少运算步骤                cnt = cnt<<1;                  temp = temp<<1;              }          }          if(!resultGreatThanZero)              ret*=-1;          //考虑到溢出        if(ret<(long)INT_MIN||ret>(long)INT_MAX)              return (int) INT_MAX;          return (int) ret;      }          private static long abs(long divisor) {            if(divisor<0){            divisor=divisor*(-1);        }    return divisor;}


0 0
原创粉丝点击