1、A+B的问题

问题描述:

  1. 方法一

     采用位运算符实现加法运算。位运算符运算的表格如下:

运算符

功能

用法

                             说明

  ~

位求反

~expr

二进制逐位求反后生成一个新值,0变1,1变0

<<

扫描二维码关注公众号,回复: 3541838 查看本文章

左移

expr1 << expr2

在右侧插入值为0的二进制位

>>

右移

expr1 >> expr2

在左侧插入值为0的二进制位

&

位与

expr1 & expr2

同为1取1,否则取0

^

位异或

expr1 ^ expr2

相同取0,不同取1

|

位或

expr1 | expr2

至少有一个为1,则为1,否则为0

 对于加法运算,先将加数(a)和被加数(b)化成二进制数,然后对 a 和 b 进行位异或(^)运算:异或运算又称不进位加法、进行位与(&)运算,将这两个结果相加即可实现加法运算。

例子:

 用到的语法:C++中的if....else语法:

if(boolean_expression)
{
   //如果不二表达式为真,将执行此处语句
}
else
{
   //如果布尔表达式为假,将执行此处的语句
}

方法一程序代码:(递归版本)

class Solution {
public:
    /**
     * @param a: An integer
     * @param b: An integer
     * @return: The sum of a and b 
     */
    int aplusb(int a, int b) {
        // write your code here
        int sum = 0;
        int sum1 = a^b;  //异或操作,得到二进制原位对应相加之后的和
        int sum2 = (a&b)<<1;  //与运算和左移运算,得相加之后进位所在位得值
        if(sum2 != 0)
        {
            sum = aplusb(sum1,sum2);  //若进位不是0,则a+b的和为原位和+进位和
        }
        else
        {
            sum = sum1;  //若进位和为0,则a+b的和直接等于异或后的结果
        }
        return sum;  //返回加法运算后的结果
        
    }
};

运行时效: 

 

2.方法二(递归版本)

使用三目运算符替代if....else语句,提高运行效率。

三目运算符: c ? x : y

                      若条件c为true,执行x的值;否则,执行y的值。

方法二的代码:

class Solution {
public:
    /**
     * @param a: An integer
     * @param b: An integer
     * @return: The sum of a and b 
     */
    int aplusb(int a, int b) {
        // write your code here
        int sum = 0;
        int sum1 = a^b;  //异或操作,得到二进制原位对应相加之后的和
        int sum2 = (a&b)<<1;  //与运算和左移运算,得相加之后进位所在位得值
        
       //使用三目运算符c ? x:y,若条件为true,则计算x的值,否则,计算y的值
        return sum2 == 0 ? sum1 : aplusb(sum1,sum2) ;  
        
    }
};

运行时效: 

3.方法三:(迭代版本)

class Solution {
public:
    /**
     * @param a: An integer
     * @param b: An integer
     * @return: The sum of a and b 
     */
     //加法运算迭代版
    int aplusb(int a, int b) {
        // write your code here
        int sum =a^b;
        int sum1 = (a&b)<<1;
        while(sum1 != 0)  //不断迭代,直到为0跳出循环
        {
            int a = sum;
            int b = sum1;
            sum = a^b;
            sum1 =(a&b)<<1;
        }
        return sum;
    }
};

运行时效: 

迭代和递归的区别:

从“编程之美”的角度看,可以借用一句非常经典的话:“迭代是人,递归是神!”来从宏观上对二者进行把握。

  • 递归:重复调用函数自身实现循环称为递归;

       递归实际上不断地深层调用函数,直到函数有返回才会逐层的返回,递归是用机制实现的,每深入一层,都要占去一块栈数据区域,因此,递归涉及到运行时的堆栈开销(参数必须压入堆栈保存,直到该层函数调用返回为止),所以有可能导致堆栈溢出的错误;但是递归编程所体现的思想正是人们追求简洁、将问题交给计算机,以及将大问题分解为相同小问题从而解决大问题的动机。

         例如:if else 调用自己,并在合适时机退出

  • 迭代:利用变量的原值推出新值称为迭代,或着说迭代是函数内某段代码实现循环

        迭代大部分时候需要人为的对问题进行剖析,分析问题的规律所在,将问题转变为一次次的迭代来逼近答案。迭代不像递归那样对堆栈有一定的要求,另外一旦问题剖析完毕,就可以很容易的通过循环加以实现。迭代的效率高,但却不太容易理解,当遇到数据结构的设计时,比如图表、二叉树、网格等问题时,使用就比较困难,而是用递归就能省掉人工思考解法的过程,只需要不断的将问题分解直到返回就可以了。

         例如:for,while循环

  • 两者关系:所有的迭代可以转换为递归,但递归不一定可以转换成迭代。

 总结如下:

  定义 优点 缺点
递归 重复调用函数自身实现循环

a.用有限的循环语句实现无限集合;

b.代码易读;

c.大问题转化成小问题,减少了代码量。

a.递归不断调用函数,浪费空间

b.容易造成堆栈溢出

迭代

利用变量的原值推出新值;

函数内某段代码实现循环。

a.效率高,运行时间只随循环的增加而增加;

b.无额外开销。

a.代码难理解;

b.代码不如递归代码简洁;

c.编写复杂问题时,代码逻辑不易想出

两者关系

a.递归中一定有迭代,但是迭代中不一定有递归;大部分可以相互转换。

b.相对来说,能用迭代不用递归(因为递归不断调用函数,浪费空间,容易造成堆栈溢出)

猜你喜欢

转载自blog.csdn.net/gaoyu1253401563/article/details/82377972