记录一下位运算的学习 牛客上的练习笔记
难度简单
编写一个函数,输入是一个无符号整数(以二进制串的形式),
返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量)。
class Solution {
public:
int hammingWeight(uint32_t n) {
int c=0;
/* 与运算有0出0 两个都为1时出1
1000 (n)
& 0111 (n-1)
_________________
0000
这样子就把最低位的1消去了
*/
while(n) //只要n没消完所有的位1
// 就一直循环 为00000结束
{
n&=(n-1);
c++;
}
return c;
}
};
难度简单
两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。给你两个整数 x 和 y,计算并返回它们之间的汉明距离。
class Solution {
public:
int hammingDistance(int x, int y) {
int n=x^y;
/* 异或运算相同出0 不同出1
1100
^1010
————————————
0110
//这样只要统计n现在位1的个数*/
int count=0;
/* 与运算有0出0 两个都为1时出1
1000 (n)
& 0111 (n-1)
_________________
0000
这样子就把最低位的1消去了 这里见位1的个数*/
while(n) //只要n没消完所有的位1
// 就一直循环 为00000结束
{
n&=(n-1);
count++;
}
return count;
}
};
难度简单
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res=0;
// 相同的数异或为0 a^a=0
// 任何数与0异或为数本身 a^0=a
for(int i=0;i<nums.size();i++)
{
//把所有的数异或完 相同的数异或为0
//最后剩下的数异或0 得到只出现一次的数本身
res=res^nums[i];
}
return res;
}
};
难度中等
编写一个函数,不用临时变量,直接交换numbers = [a, b]中a与b的值。
class Solution {
public:
vector<int> swapNumbers(vector<int>& numbers) {
/* 相同的数异或为0 a^a=0
任何数与0异或为数本身 a^0=a
满足交换律和结合律
a=a^b;
b=a^b=a^b^b=a^0=a
a=a^b=a^b^a=a^a^b=b */
numbers[0]=numbers[0]^numbers[1];
numbers[1]=numbers[0]^numbers[1];
numbers[0]=numbers[0]^numbers[1];
return numbers;
}
};
难度中等
给你两个整数 a 和 b ,不使用 运算符 + 和 - ,计算并返回两整数之和。
class Solution {
public:
int getSum(int a, int b) {
/* 异或运算相同出0 不同出1
1100
^1010
————————————
0110 等于不带进位的加法
a^b 即为不考虑进位的情况下a和b的加和
1100
+1011
——————————
10110 当a和b对应位都为1时 才有可能产生进位 &运算
不带进位的加和 + 带进位加和的值 为所求
a^b + (a&b)<<1
*/
if(b==0) //递归出口
{
return a;
}
else{
return getSum(a^b,(unsigned int)(a&b)<<1);
}
// return b==0?a:getSum(a^b,(unsigned int)(a&b)<<1);
}
};
位运算中异或的使用较为巧妙,要学习上手有很大的难度。 学废了学废了!
学习自b站up主:英雄哪里出来 位运算合集
总结:与运算 & 有0出0 两个都为1时出1
或运算 | 有1出1 两个都为0时出0
异或运算 ^ 相同出0 不同出1