LeetCode:Sum of Two Integers - 不使用加减法运算符的整数加法

1、题目名称

Sum of Two Integers(不使用加减法运算符的整数加法)

2、题目地址

https://leetcode.com/problems/sum-of-two-integers/

3、题目内容

英文:

Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.

中文:

计算两个整数的和,但不允许使用运算符+和-

4、解题方法1

虽然题目中明确表示不让用户使用加法运算符与减法运算符,不过下面两种写法还是能获得Accept:

1)Java代码:直接使用a+b作为返回值

public class Solution {
    public int getSum(int a, int b) {
        return a + b;
    }
}

2)Java代码:使用a-(-b)作为返回值

public class Solution {
    public int getSum(int a, int b) {
        return a - (-b);
    }
}

5、解题方法2

解题方法1中列举的两种方法虽然能获得Accept,但以这种方式解题明显不是命题人的本意。既然不让用加减法解决两数求和的问题,那我们就只能求助位运算了。

设相加的两数为a和b,解题思路如下:

1、如果不考虑进位,a^b为a+b中各位数字相加的和

2、如果考虑进位,(a&b)<<1为各位数字相加后应有的进位

3、a+b可以转换为其等价形式(a^b)+(a&b)<<1

4、当(a&b)为0时,(a&b)<<1也为0,此时a^b即为所求

写成Java代码,就是:

/**
 * 不使用加减法运算符的整数加法
 * @文件名称 Solution.java
 * @文件作者 Tsybius2014
 * @创建时间 2016年7月19日 上午9:37:37
 */
public class Solution {
    /**
     * 不使用加减法运算符的整数加法
     * @param a 加数a
     * @param b 加数b
     * @return a与b的和
     */
    public int getSum(int a, int b) {
        int x = a & b;
        int y = a ^ b;
        if (x == 0) {
            return y;
        } else {
            return getSum(y, x << 1);
        }
    }
}

如果还不能理解这段代码,可以用下面的方式打印计算中的各中间值:

/**
 * 不使用加减法运算符的整数加法
 * @文件名称 Solution.java
 * @文件作者 Tsybius2014
 * @创建时间 2016年7月19日 上午9:37:37
 */
public class Solution {
    /**
     * 不使用加减法运算符的整数加法
     * @param a 加数a
     * @param b 加数b
     * @return a与b的和
     */
    public int getSum(int a, int b) {
        printNum(a, b);
        int x = a & b;
        int y = a ^ b;
        if (x == 0) {
            return y;
        } else {
            return getSum(y, x << 1);
        }
    }
    
    /**
     * 打印中间结果
     * @param num1 加数a
     * @param num2 加数b
     */
    public void printNum(int num1, int num2) {
        System.out.println("----- PRINT NUM -----");
        //加数a
        String bin1 = Integer.toBinaryString(num1);
        while (bin1.length() < 32) bin1 = "0" + bin1;
        String res1 = "a:" + num1 + "\n bin(a):" + bin1;
        System.out.println(res1);
        //加数b
        String bin2 = Integer.toBinaryString(num2);
        while (bin2.length() < 32) bin2 = "0" + bin2;
        String res2 = "b:" + num2 + "\n bin(b):" + bin2;
        System.out.println(res2);
        //a&b
        String bin3 = Integer.toBinaryString(num1 & num2);
        while (bin3.length() < 32) bin3 = "0" + bin3;
        String res3 = "&:" + (num1 & num2) + "\n bin(&):" + bin3;
        System.out.println(res3);
        //a^b
        String bin4 = Integer.toBinaryString(num1 ^ num2);
        while (bin4.length() < 32) bin4 = "0" + bin4;
        String res4 = "^:" + (num1 ^ num2) + "\n bin(^):" + bin4;
        System.out.println(res4);
        //a+b
        String bin5 = Integer.toBinaryString(num1 + num2);
        while (bin5.length() < 32) bin5 = "0" + bin5;
        String res5 = "+:" + (num1 + num2) + "\n bin(+):" + bin5;
        System.out.println(res5);
        System.out.println();
    }
}

另a为123,b为456,控制台中打印的结果如下:

----- PRINT NUM -----
a:123
 bin(a):00000000000000000000000001111011
b:456
 bin(b):00000000000000000000000111001000
&:72
 bin(&):00000000000000000000000001001000
^:435
 bin(^):00000000000000000000000110110011
+:579
 bin(+):00000000000000000000001001000011

----- PRINT NUM -----
a:435
 bin(a):00000000000000000000000110110011
b:144
 bin(b):00000000000000000000000010010000
&:144
 bin(&):00000000000000000000000010010000
^:291
 bin(^):00000000000000000000000100100011
+:579
 bin(+):00000000000000000000001001000011

----- PRINT NUM -----
a:291
 bin(a):00000000000000000000000100100011
b:288
 bin(b):00000000000000000000000100100000
&:288
 bin(&):00000000000000000000000100100000
^:3
 bin(^):00000000000000000000000000000011
+:579
 bin(+):00000000000000000000001001000011

----- PRINT NUM -----
a:3
 bin(a):00000000000000000000000000000011
b:576
 bin(b):00000000000000000000001001000000
&:0
 bin(&):00000000000000000000000000000000
^:579
 bin(^):00000000000000000000001001000011
+:579
 bin(+):00000000000000000000001001000011

END

转载于:https://my.oschina.net/Tsybius2014/blog/714382

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值