力扣:16.09. 运算

189 阅读1分钟

「这是我参与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%的用户