当前位置: 首页 > news >正文

牛客网:JZ65 不用加减乘除做加法(详解)

前言:本期是关于JZ65 不用加减乘除做加法的详解,内容包括四大模块:题目,代码实现,大致思路,代码解读,今天你c了吗?

 题目:

 

描述

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

数据范围:两个数都满足−10≤n≤1000
进阶:空间复杂度 O(1),时间复杂度O(1)

示例1

输入:

1,2

返回值:

3

示例2

输入:

0,0

返回值:

0

代码实现:

 int Add(int num1, int num2 )
 {
    // write code here
   
    while(num2!=0)
    {
        int tmp = num1^num2;
        num2 = (num1&num2)<<1;
        num1 = tmp;
    }
    return num1 ;
}

大致思路:

1. 用户输入的两数是十进制数字,但在计算机中存储的是二进制形式,故而相加减都是以两数的二进制形式进行的

2. 举个例子:输入 5 7,求5+7,结果是12

算法(十进制版):

a. 求出两数不进位相加的结果

b. 求出两数应该进的位

c. 两数之和=两数不进位相加的结果+两数应该进的位

5+7=       2                            +                                              10                                           =12

        5+7不进位的结果                     5+7应该向前进一位(在个位向前进一位得到一个十)

我们真正要使用的是二进制版的算法

算法(二进制版):

5的二进制形式:0101                       7的二进制形式:0111

现求5+7 起始就是求 0101+0111

两个二进制数相加(比如 0101+0111)的求和算法:

    1. 求出0101和0111不进位相加的结果:(二进制是逢2进1)

        不进位即:1+1=0(因为逢2进1),0+0=0,0+1=1

         演示:0        1        0        1

                 + 0        1       1         1

         结果:0         0       1         0

                 

        0101和0111不进位相加的结果可以通过两数异或^得到

        按位异或^  : 相同则0,相异则1

    2. 求出0101和0111应该进的位:

         step1:找包含出能产生进位效果的比特位的二进制数

                  (即找出两二进制数所对应比特位上都是1的)

         step2:将包含出能产生进位效果的比特位的二进制数运用左移操作符 

                      即可得到0101和0111应该进的位

   3.   0101和0111不进位相加的结果+两数应该进的位

          又是两个二进制形式的数相加,重复两个二进制数相加的算法

           直至两个二进制数应该进的位变成0,循环结束

代码解读:

 int Add(int num1, int num2 )
 {
    // write code here
   
    while(num2!=0)
    {
        int tmp = num1^num2;
        num2 = (num1&num2)<<1;
        num1 = tmp;
    }
    return num1 ;
}

num1和num2在内存中以二进制的形式存储

num1:存储两二进制数不进位相加(按位异或^)的结果

num2:存储两二进制数应该进的位(按位与&后再左移<<1位)

简洁版:

1.两二进制相加,只要两二进制应该进的位不为0,

                  则就要继续另外一对二进制数的相加(新的原身)

                  另外的一对二进制数:两原身二进制数不进位相加的结果和两原身二进制数应该进的位

                   另外一对二进制数的相加就要求出这另外一对二进制数

                  a. 两原身二进制数按位异或得到  b. 两原身二进制数按位与后再左移1位得到

2. 当在一对二进制的相加中,它们进的位位0了,则计算完毕,结束while循环

形象一点:将原来相加的二进制数0101和0111想象成掌权者,掌权者位置有两个,掌权者1的位置上是上一任掌权者们不进位相加的结果,掌权者2的位置上是上一任掌权者们应该进的位,

当掌权者2的位置上的数值不为0时,表示国力强盛,扩张了领土,需要产生另一对掌权者治理

故而掌权者1位置上的数值和掌权者2位置上的数值要产生和它们同源的新的掌权者,继承扩张领土上的两个掌权者位置

当掌权者2位置上的数位0时,表示全部领土已扩张完毕。

解析版:我们以(5)0101+0111(7)的求和为例:

1. 得到两二进制数按位异或(两二进制数不进位相加)的结果存储至tmp中

    0101^0111 -> 0010

    以易理解的十进制视角:

    5+7不进位的结果是2,即按位异或所得的二进制0010转化成十进制就是2

2. 得到两二进制数应该进的位

     a. 首先求出包含产生进位效果的比特位的二进制数:两二进制数按位与得到

     0101&0111 -> 0101

     按位与&:两个位置上都是1才是1

     能产生进位效果的比特位:两个对应的比特位上都是1(标红)

0101
                                                                  +0111
包含产生进位效果的比特位的二进制数:0 101

    相加后能产生进位效果的比特位上保留1,其余普通比特位置0

   b. 其次将包含进位效果比特位的二进制数0101向左移动一位,

       得到的二进制数1010就是应该进的位

       以易理解的十进制视角:

        5+7应该进的位是10,即得到的二进制位1010转化成十进制就是10

3. 两二进制数不进位相加的结果0010+两二进制数应该进的位1010

    两二进制数相加按照上面的算法,重复如下操作:

    a.  得到两二进制数按位异或(两二进制数不进位相加)的结果

    b. 得到两二进制数应该进的位

    3. 不进位相加的结果+应该进的位

          又重复两二进制求和的算法,故而我们写成一个while循环

           结束两二进制求和的条件是:两二进制数应该进的位=0

           就像十进制的5+7,当5和7不进位相加的结果2+应该进的位10后,

           没有要进的位了,要进的位数值是0,结束了5+7的计算,得到结果12

相关文章:

  • 设计模式:观察者模式
  • C/C++基础 memset()函数的用法
  • LeetCode 2176. 统计数组中相等且可以被整除的数对
  • 直线生成算法(DDA算法)
  • 10技术太卷我学APEX-导航卡Card
  • 红黑树插入结点
  • python入门 之 字典(六)
  • 通过python编写自定义尺寸和位置批量进行图像剪裁
  • 开发人员对需求的正确打开方式
  • SQLSERVER 快照隔离级别 到底怎么理解?
  • 《SQL基础》09. 事务
  • 设计模式-第1章(简单工厂模式)
  • springboot,vue教务管理系统
  • 5.6 频率响应与阶跃响应
  • Next.js 中的 SEO
  • 初识Linux基础工具之yum vim gcc gdb git以及简单makefile文件的编写
  • Traffic Signs Recognition with 95% Accuracy using CNNKeras
  • axios中params和data的区别
  • 【QT】C++和QML使用多线程优化界面切换卡顿的方法
  • kob后端1
  • 电加热油锅炉工作原理_电加热导油
  • 大型电蒸汽锅炉_工业电阻炉
  • 燃气蒸汽锅炉的分类_大连生物质蒸汽锅炉
  • 天津市维修锅炉_锅炉汽化处理方法
  • 蒸汽汽锅炉厂家_延安锅炉厂家
  • 山西热水锅炉厂家_酒店热水 锅炉
  • 蒸汽锅炉生产厂家_燃油蒸汽发生器
  • 燃煤锅炉烧热水_张家口 淘汰取缔燃煤锅炉
  • 生物质锅炉_炉
  • 锅炉天然气_天燃气热风炉