剑指offer(51):不用加减乘除做加法
来源:互联网 发布:2015十大网络流行语 编辑:程序博客网 时间:2024/06/05 13:35
题目描述
写一个函数,求两个整数的和,要求在函数体内不得使用加减乘除四则运算。
分析
对于数字的运算,如果不能使用常规的加减乘除四则运算,那就是能使用位运算了。
考虑十进制下5+17=22
的结果。第一步只做各位相加不进位,则相加的结果是12(因为个位上5+7=12
,不处理进位的话,认为结果是2;十位上0+1=1
结果是1,则十位个位合并的结果是12);第二步处理进位,5+7
中有进位,进位的值是10;第三步将两个结果加起来,12+10=22
也就是原来5+17=22
的结果。
在考虑二进制下的情况5+17=22
(10进制)在二进制下101+10001=10110
仍然成立。第一步仍然只做各位相加不进位,则结果为10100(最低位的1+1=10
,由于不进位,最低位的结果仍然是0);第二步几下进位,这里进位只有最低位相加产生的进位10;第三步,将前两部结果相加,即10100+10=10110
。
接着考虑用位运算代替前面的加法。第一步不考虑进位的每一位相加,0加0、1加1不考虑进位结果为0,0加1、1加0不考虑进位结果为1,这和异或运算的结果相同;第二步进位的情况是,0加0、0加1、1加0都不会产生进位,只有1加1才进位,这和与运算的结果比较符合,因此这一步可以看成两个数字先做位与运算,然后再向左移动一位;第三步,将前面两个结果相加,这个过程仍然是重复前面两步,知道不产生进位为止。
牛客AC:
/** * 写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。 * * key: * 1、位异或运算模拟不考虑进位的加法 * 2、位与运算后左移一位模拟进位 * 3、将前面两步结果相加 * 4、重复运算直到不再产生进位 * * @param num1 * @param num2 * @return */ public int add(int num1,int num2) { int sum = 0, carry = 0; do { sum = num1 ^ num2; // 位异或运算模拟不考虑进位的加法 carry = (num1 & num2) << 1; // 位与运算后左移一位模拟进位 // 更新赋值,循环将前面两步结果相加 num1 = sum; num2 = carry; } while(num2 != 0); // 重复运算直到不再产生进位 return sum; }
问题扩展
不适用新的变量,交换两个变量的值。
1、使用加法
/** * 不使用新的变量交换两个变量 * @param a * @param b */ public void swap(int a, int b) { a = a + b; b = a - b; // 即 b = ((a+b) - b) = a a = a - b; // 即 a = ((a+b) - a) = b }
2、使用位异或运算
/** * 不使用新的变量交换两个变量 * * 使用位异或运算 * * @param a * @param b */ public void swap2(int a, int b) { a = a ^ b; b = a ^ b; a = a ^ b; }
参考
1. 何海涛,剑指offer名企面试官精讲典型编程题(纪念版),电子工业出版社
0 0
- 剑指offer(51):不用加减乘除做加法
- 【剑指offer】不用加减乘除做加法
- 【剑指offer】不用加减乘除做加法
- 剑指Offer之 - 不用加减乘除做加法
- 剑指offer: 不用加减乘除做加法
- 剑指offer 不用加减乘除做加法
- 《剑指offer》不用加减乘除做加法
- 剑指offer--不用加减乘除做加法
- 剑指offer:不用加减乘除做加法
- 【剑指offer】之不用加减乘除做加法
- 剑指offer-不用加减乘除做加法
- 《剑指offer》不用加减乘除做加法
- 剑指offer:不用加减乘除做加法
- 剑指Offer--047-不用加减乘除做加法
- 剑指offer题解 不用加减乘除做加法
- 《剑指offer》:[47]不用加减乘除做加法
- 《剑指offer》-不用加减乘除做加法
- 剑指offer 不用加减乘除做加法
- 应用程序指定IE版本
- unity编译时自动结束项目运行
- SDL播放wav格式的音乐
- 电学发展史
- 一个Activity掌握Android5.0新控件
- 剑指offer(51):不用加减乘除做加法
- Jquery uploadify 多余的Get请求(404错误)
- spring对乱码的处理及其springmvc核心器注册
- 算法(1)--插入排序
- 关于Ubuntu apt-get update 失败,问题解决
- EasyUI扩展 datagrid列名包含特殊字符会导致表格错位(5)
- 建立一棵二叉树
- Android通过Servcie实现Notification定时发送
- 在无头单链表的一个非头节点前插入一个节点