面试题 16.09. 运算

不用乘除减实现乘法的题在之前遇到过一道,我还记得那道题的解题思路是看一个数末尾跟进行与运算,如果是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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值