「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
描述
请实现整数数字的乘法、减法和除法运算,运算结果均为整数数字,程序中只允许使用加法运算符和逻辑运算符,允许程序中出现正负常数,不允许使用位运算。
你的实现应该支持如下操作:
Operations() 构造函数 minus(a, b) 减法,返回a - b multiply(a, b) 乘法,返回a * b divide(a, b) 除法,返回a / b
- 示例 1:
Operations operations = new Operations();
operations.minus(1, 2); //返回-1
operations.multiply(3, 4); //返回12
operations.divide(5, -2); //返回-2
- 提示:
- 你可以假设函数输入一定是有效的,例如不会出现除法分母为0的情况
- 单个用例的函数调用次数不会超过1000次
解析
思路如下:
- 减法,等于 a-b=a+(-b)。
- 加法不用 加号去解的话可以使用二进制的加分,计算a+b,等价于(a^b)+((a&b)<<1)。
- ((a&b)<<1) 是进位符,只要判断进位是否为0的时候可以一直加。
- 乘法的本质是n个数相加,参考快速幂的思路,在开始时判断符号位将其转换为正数
- 除法是n个数相减,使用快速相减的方法计算。
class Operations {
public Operations() {
}
public int minus(int a, int b) {
b=-b;
while(b != 0) {
int c = (a & b) << 1;
a ^= b;
b = c;
}
return a;
}
public int multiply(int a, int b) {
int ans = 0;
boolean flag=a>0?(b <= 0):(b > 0);
a=a>0?a:-a;b=b>0?b:-b;
while (b > 0) {
if ((b & 1) == 1) {
ans = ans + a;
}
a <<= 1;
b >>= 1;
}
return flag?-ans:ans;
}
public int divide(int dividend, int divisor) {
boolean s = (dividend ^ divisor) >= 0;
long d1 = (long) dividend;
long d2 = (long) divisor;
d1 = d1 > 0 ? d1 : -d1;
d2 = d2 > 0 ? d2 : -d2;
if (d1 < d2)
return 0;
long d = 0x40_00_00_00_00L, c = 0L, res = 0L;
while (d != 0) {
c = (c << 1) | ((d & d1) == 0 ? 0 : 1);
if (c >= d2) {
res = (res << 1) | 1;
c -= d2;
} else {
res = res << 1;
}
d = d >> 1;
}
return s ? res > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)res : (int)-res;
}
}
/**
* Your Operations object will be instantiated and called as such:
* Operations obj = new Operations();
* int param_1 = obj.minus(a,b);
* int param_2 = obj.multiply(a,b);
* int param_3 = obj.divide(a,b);
*/
运行结果:
执行结果:通过
执行用时:18 ms, 在所有 Java 提交中击败了56.19%的用户
内存消耗:38.4 MB, 在所有 Java 提交中击败了60.95%的用户