文章目录
基础知识
1.移位运算
<< : 左移运算符,num << 1,相当于num乘以2
>> : 右移运算符,num >> 1,相当于num除以2
>>>: 无符号右移,忽略符号位,空位都以0补齐
一、二进制中1的个数
1.题目
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
2.思路
逐位和1进行与操作。如果返回1则计数cont加一。
逐位实现的思路: 每比较一次,该数进行无符号右移一次(n=n>>>1)
3.代码
public class Solution {
public int NumberOf1(int n) {
int cont = 0;
while(n!=0){
cont = cont +(n&1); //比较当前末位是否为1
n = n>>>1; //无符号右移一次
}
return cont;
}
}
二、不用加减乘除做加法
1.题目
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
2.思路
加法的实现原理(分为逐位和+进位和)
- 获取逐位相加的结果
- 获取进位的值
- 不断将这两个结果在此相加,直到没有进位(即代码中的num2为0)。
(1)对于十进制的加法
4. 首先不考虑进位,首先逐位相加,得到的结果与进位结果相加。
5. 不断迭代直到没有进位
对于12+19 = 31
12+19,逐位相加,
得到21,进位10,逐位相加,
31,进位0,得到结果。
(2)对于二进制的加法
- 两个数异或:相当于每一位相加,而不考虑进位
- 两个数相与,并左移一位:相当于求得进位
13+11 = ?;
13 的二进制 1 1 0 1 -----a 13
11 的二进制 1 0 1 1 -----b 11
(a&b)<<1 1 0 0 1 0 -----d 18
a^b -> 0 1 1 0 -----e 6
(d&e)<<1 0 0 1 0 0 ------f 4
d^e 1 0 1 0 0 -----g 20
(f&g)<<1 0 1 0 0 0 ------h 8
f^g 1 0 0 0 0 ------i 16
(h&i)<<1 0 0 0 0 0 ------h 0 --------退出循环
h^i 1 1 0 0 0 ------i 24
3.代码
public class Solution {
public int Add(int num1,int num2) {
int sum = num1;//保证当num2为0时候返回num1
int carry = 0;
while(num2 != 0) {
sum = num1 ^ num2; //两个数异或:相当于每一位相加,而不考虑进位
carry = (num1 & num2) << 1;//两个数相与,并左移一位:相当于求得进位
num1 = sum;
num2 = carry;
}
return sum;
}
}
4.拓展,用二进制来做减法
-n = ~n+1
然后a-b = a+(-b)即可。
三、求1+2+3+…+n
1.题目
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
2.思路
- 不让用任何关键字。但是该求和问题的关键就是如何让求和过程停下来。即判断(n>0)。
- 所以要使用这个boolean量(n>0),可以用递归。
- (n>0) && ((sum+=Sum_Solution(n-1))>0)
1. 当n==0时,(n>0)&&((sum+=Sum_Solution(n-1))>0)只执行前面的判断,为false,然后直接返回0。
2. 当n>0时,执行sum+=Sum_Solution(n-1),实现递归计算Sum_Solution(n)。
3.代码
public class Solution {
public int Sum_Solution(int n) {
int sum = n;
boolean temp = (n>0) && ((sum+=Sum_Solution(n-1))>0);
return sum;
}
}