在剑指offer上有一道不用加减的加法,给了很多稀奇古怪的解法,今天想找来看看,找不到这本书了。。
我不知道左移和右移算不算作弊了,因为本质上还是乘除了。不能用乘除,可以用加减。一个一个的加上去,看看能加多少个除数,果断超时了。计算机很神奇,最神奇的地方就是能把多复杂的事情,都转化成01两种操作,二分,二倍,像算法里的01,是很多算法的基础。当一个个加不行的时候,想想每次double嘛,不仅double除数,还要double计数值。double了有个问题,如果double之后会超过被除数怎么办呢?那这次就别double了,先减去一下目前已经统计过的除数,下次除数从头开始加。
其实还有一个问题需要注意,乘法和除法在转化为加减运算时,一定要先把符号统一一下,比较简单的做法可以是设置标记位,再用无符号数处理。
class Solution {
public:
int divide(int dividend, int divisor) {
int res = 0, count;
long long sum;
bool flag = false;
if((dividend<0&&divisor>0)||(dividend>0&&divisor<0))
flag = true;
long long tdividend = dividend;
long long tdivisor = divisor;
long long mdividend = abs(tdividend);
long long mdivisor = abs(tdivisor);
if(mdivisor>mdividend) return 0;
while((mdivisor>1)&&((mdivisor&1) == 0)){
mdividend>>=1;
mdivisor>>=1;
}
if(mdivisor==1) return flag?-mdividend:mdividend;
while(mdividend>=mdivisor){
count = 1;
sum = mdivisor;
while(mdividend>=sum+sum){
sum += sum;
count += count;
}
res += count;
mdividend -= sum;
}
return flag?-res:res;
}
};