LintCode_两个整数相除
2015-11-27 15:55
323 查看
问题描述:
将两个整数相除,要求不使用乘法、除法和 mod 运算符。如果溢出,返回
样例:给定被除数 =
=
算法思想:
方法一:(这是开始自己想出来的,算法思想简单,缺点是,循环次数多,运行速度慢)
如果不能采用乘除运算方法,那么可以采用加减方式,当然还要(1)、注意分类:正正,正负,负正,负负;(2)、溢出问题;
注:此题在测试过程中,最纠结的就是碰到-2147483648等的溢出问题,例如被除数和除数都是-2147483648时,如果,在最开始没有使用
语句,result最终结果为2147483647。在负负情况下添加添加打印result和dividend的语句,可以看到result和dividend在while循环中的结果,很奇怪;如果被除数和除数是其他数据,运行结果正常。因此,这不是逻辑问题,而是溢出!
方法二:百度了下别人的做法,发现可以使用位运算,减少循环步骤,大大减少了运算时间,在被除数很大,除数很小的时候很有优势。因为左移一位相当于数字乘2;所以有时左移右移运算配合加减法,就相当于乘除法;
将两个整数相除,要求不使用乘法、除法和 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; }
相关文章推荐
- 基于matlab的三维柱状图绘制
- CTCallCenter 的使用心得
- cvCaptureFromFile一直返回NULL
- [转]Android 如何对sqlite数据库进行增删改[insert、update和delete] 操作
- jquery 下拉列表级联
- Guava学习笔记:Google Guava 类库简介
- 转:Oracle表分区
- Shell case正则匹配法
- js模块化开发——模块的写法
- iOS判断手机号邮箱网址的正则
- 拉萨旅游攻略
- android studio jcenter
- 网络爬虫:基于对象持久化实现爬虫现场快速还原
- 网络爬虫:基于对象持久化实现爬虫现场快速还原
- sublime 快捷键大全
- Linux kernel Panic后自动重启机器的设置
- mysqlbinlog 查看执行的sql (row模式)
- spatialhadoop2.1源码阅读(二) bin/shadoop generate命令
- 源码二:SimpleAdapterimple与Sqlite的使用
- Linux下修改网卡IP、DNS和网关