不用加减乘除做加法

不用加减乘除做加法

  • 一、描述
  • 二、方法

一、描述

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号,本题OJ链接
数据范围:两个数都满足 −10≤n≤1000
进阶:空间复杂度 O(1),时间复杂度 O(1)

二、方法

分析:本题要求不能使用+、-、*、/,所以我们应该从二进制的角度去考虑,因为二进制的加法可以通过与(&)、或(|)、左移(<<)和或(|)来完成,并且二进制的话不用考虑正负数,直接对补码进行加法运算就行。但是具体怎么加呢?人去计算二进制相加很简单,直接通过肉眼就可以判断哪里要进位,哪里不需要,然后再最终相加,但是电脑不会这样做,那该怎么办呢?
思路:通过十进制相加思想推导出二进制相加思想
十进制相加思想(和平常的直接加法不同):
1、如果两数相加每一位都不会产生进位,则直接相加就是最终结果
2、如果两数相加会产生进位(无论哪几位产生进位都行),先计算不考虑进位的相加结果,记作a,再计算进位,记作b,然后把a和b看作新得到的两个数相加,看是情况1还是情况2,一直这样下去,直到计算出结果
例如,如下图所示:
不用加减乘除做加法_第1张图片
二进制相加思想
和上面十进制相加思想一样,只不过:
1、有没有产生进位通过相与来判断,相与结果为0,没有进位,否则,有进位。没有进位,两数相或就是最终结果;有进位,需要进一步计算,与的结果左移一位就是最终的进位
2、不考虑进位的相加结果通过异或可以完成
例如,如下图所示:
不用加减乘除做加法_第2张图片
分析:产生多少次进位,就循环多少次,最多不超过32次进位,时间复杂度O(1),空间复杂度O(1)
代码实现:

int Add(int a, int b )
{
    int n1 = 0;
    int n2 = 0;
    while(a & b) //判断是否有进位,有进位一直循环计算,直到没有进位为止
    {
        n1 = (a & b) << 1; //最终的进位
        n2 = a ^ b; //不考虑进位的相加结果
        a = n1; //作为新的a
        b = n2; //作为新的b
    }
    return a | b; //此时a&b不会产生进位,计算最终结果
}

你可能感兴趣的:(OJ,leetcode,算法)