不用乘除减实现乘法的题在之前遇到过一道,我还记得那道题的解题思路是看一个数末尾跟进行与运算,如果是0的话表明可以被2整除,我么利用位移让它除以2,让另外一个数乘以2,如果是1的话,就直接用加法加上这个数。。。。
但是这个题要求不用位运算,要实现减法,直接加一个相反数就好了。关键是取反。
我们可以同样的把二进制存储入数组,分别代表用poss存储1,2,4.。。一直int的最大值,用negs存储-1,-2,-4.。。一直到int的最小值,取反的实现我们是先判断传进来的数是正数还是负数,如果是整数,那么要把它变为负数,所以我们遍历的是negs,反向遍历,看哪些位相加可以把这些数抵消掉,把这些位相加就是相反数。
乘法就是有b个a相加,我们通过指数递增的方式从1开始加,保证它小于b,然后每次让指数数次的a相加,最后就是结果。
除法也是一样,只不过根据a的正负,分成同正同负的情况。最后都转成大于0处理。
class Operations {
static int[] negs=new int[32];
static int[] poss=new int[32];
public Operations() {
int pos = 1, neg = -1;
for (int i = 0; i < 30; i++) {
poss[i] = pos;
negs[i] = neg;
pos += pos;
neg += neg;
}
poss[30] = pos;
negs[30] = neg;
}
public int opposite(int a) {
if (a == 0) return 0;
int res = 0;
if (a > 0) {
for (int i = 30; i >= 0; i--) {
if (negs[i] + a < 0) continue;
a += negs[i];
res += negs[i];
}
} else {
for (int i = 30; i >= 0; i--) {
if (poss[i] + a > 0) continue;
a += poss[i];
res += poss[i];
}
}
return res;
}
public int minus(int a, int b) {
return a + opposite(b);
}
public int multiply(int a, int b) {
if (a == 0 || b == 0) return 0;
if (a == 1) return b;
if (b == 1) return a;
if (b < 0) return opposite(multiply(a, opposite(b)));
int res = a;
int t = 1;
while (t < poss[30] && t + t <= b) {
res += res;
t += t;
}
res += multiply(a, minus(b, t));
return res;
}
public int divide(int a, int b) {
if (a == 0) return 0;
if (b == 1) return a;
int res = 1;
if (a > 0) {
if (b == Integer.MIN_VALUE) return 0;
if (b < 0) return opposite(divide(a, opposite(b)));
if (a < b) return 0;
int mark = b;
while (mark < poss[30] && mark + mark <= a) {
res += res;
mark += mark;
}
res += divide(minus(a, mark), b);
} else {
return divide(opposite(a),opposite(b));
}
return res;
}
}