使用移位运算和加减法实现乘除法
2016-04-07 19:41
260 查看
这个想法是在做leetcode 的题目29 Divide
Two Integers时产生的,原题描述如下:
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
就是说不用乘除取余运算来实现两个int醒变量的整除,然后如果溢出的话就返回INT_MAX。
先把问题简化一下,不考虑溢出问题,并且假设被除数n大于除数m大于0,嗯,基于这个假设,剩下的就是纯粹的算法部分了。说到整除问题,有n/m==k+r(r==n mod m),也就是我们小学学过的被除数除以除数等于商加余数。根据这个公式很自然的想到用n逐次减去m直到差小于m,代码如下;
如果n和m比较接近的话,这样做还是很快的,但是对于一般情况,其时间复杂度为O(n/m),有些捉急,尤其是n特别大而m又很小的时候,简直不能忍,按这种思路提交的算法会提示超时(意料之中)。那么有没有别的方法呢?显然有!答案就是位运算。
使用左移和右移可以很方便地实现乘除2^的n次方,而 n/m==k+r 即 m*k==n-r 即 m*(2^l1+2^l2+……+2^ls)==n-r ,即m<<l1+m<,l2+……+m<<ls==n-r,于是整除运算就转化为移位运算和加减运算。然后可以写出如下代码:
这样一来,一般情况下的时间复杂度大大降低,只有O(k的二进制表示的位数)。
同理,整数乘法也可以用位运算来实现。
以上就是我能想到的方法,然后具体到这个题目的话,还要考虑除数为0以及溢出问题,比如被除数为-2^31时该怎么解决。
Two Integers时产生的,原题描述如下:
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
就是说不用乘除取余运算来实现两个int醒变量的整除,然后如果溢出的话就返回INT_MAX。
先把问题简化一下,不考虑溢出问题,并且假设被除数n大于除数m大于0,嗯,基于这个假设,剩下的就是纯粹的算法部分了。说到整除问题,有n/m==k+r(r==n mod m),也就是我们小学学过的被除数除以除数等于商加余数。根据这个公式很自然的想到用n逐次减去m直到差小于m,代码如下;
int i=0; while (n>=m) { n-=m; i++; } return i;
如果n和m比较接近的话,这样做还是很快的,但是对于一般情况,其时间复杂度为O(n/m),有些捉急,尤其是n特别大而m又很小的时候,简直不能忍,按这种思路提交的算法会提示超时(意料之中)。那么有没有别的方法呢?显然有!答案就是位运算。
使用左移和右移可以很方便地实现乘除2^的n次方,而 n/m==k+r 即 m*k==n-r 即 m*(2^l1+2^l2+……+2^ls)==n-r ,即m<<l1+m<,l2+……+m<<ls==n-r,于是整除运算就转化为移位运算和加减运算。然后可以写出如下代码:
int k=0,i=o; while (n>=m) { if (n>=m<<i) { k+=1<<i; n-=m<<i; ++i; } else { i--; } } return k;
这样一来,一般情况下的时间复杂度大大降低,只有O(k的二进制表示的位数)。
同理,整数乘法也可以用位运算来实现。
int i=0,k=0; while (m) { if (m>=1<<i) { k+=n<<i; m-=1<<i; i++; } else { i=0; } }
以上就是我能想到的方法,然后具体到这个题目的话,还要考虑除数为0以及溢出问题,比如被除数为-2^31时该怎么解决。
相关文章推荐
- Largest Rectangle in Histogram
- 深入理解 JavaScript 中的 replace 方法
- 本周学习心得
- 虚拟机VM tools的安装实现虚拟机中内容能够拷贝到本机上
- lintcode: Subsets II
- HistCite学习
- 字符串匹配:KMP算法的实现以及理解
- 学习进度表
- 第七周总结
- 结对编程黄金点游戏
- 积极暗示不仅励志而且助健康!
- Codeforces Round #346 (Div. 2) A. Round House
- 创建CALayer
- System Verilog学习笔记(一)
- 实现三级联动
- DrangonBorns
- 吐槽《C++ GUI Qt4 编程》这本书
- 简单理解 unix (liunx)inode
- Android 倒计时功能的实现
- splay