题目描述:编程实现两个正整数的除法,当然不能用除法操作符。
// return x/y.
int div(const int x, const int y)
{
....
}
位移运算的方法:
#include
intdiv(constintx,constinty)
{
intdividend = x, multi, result = 0;
while(dividend >= y)
{
multi = 1;
while( multi * y <= (dividend >> 1) )
{
multi <<= 1;
}
result += multi;
dividend -= multi * y;
}
returnresult;
}
intmain()
{
intx, y;
while( scanf("%d %d", &x, &y) != EOF )
{
printf("%d÷%d=%d/n", x, y, div(x, y));
}
return0;
} ——————————————————————————————————————————————————
个人的想法:
x/y=(x-y)/y+1
=(x-y-y)/y+2
...
=(x-n*y)/y+n
=....
结束的条件为:x-n*y>=y,并且,x-(n+1)*y
此时,n即为所求。
题目还可以稍微转换一下描述,比如,不使用 "%" && "/" 求 a % b。
步骤:
1,利用上面的方法求得[x/y],代替取整;
2,a%b=a-b*[a/b]
___________________________________________________________________________________________________
解法
1. f(x,y) = f(y, y%x) (y>0) 辗转相除法
2. 取模运算较为耗时, 将取模变成相减. 但对极端数据效果很差, 比如 gcd(1000,1)
3. 分析公约数的特点.
3.1 若 x,y 均为偶数, 那么 f(x,y) = 2*f(x/2, y/2)
3.2 若 x 为偶数, y 为奇数, 那么 f(x,y) = 2*f(x/2, y)
3.3 若都为奇数, f(x,y) = f(x, x-y) 那么下一步肯定有一个偶数
3.4 这样一来, 时间复杂度下降到 o(log(max(x,y)))