一,位运算
1,位运算的介绍
位运算本质上就是计算机最本质的运算操作,我们知道先阶段的计算机还是冯~诺伊曼为主要结构的计算机,计算机的运算方式还是二进制运算的方法,位运算就是这种的二进制运算,详细理解位运算能够使我们更加迅速的解决问题,我们在学习位运算的时候可以通过二进制表示的方法来理解位运算操作。
2,常见的运算符
1, & 位与运算
位与运算使一个二元的运算符,他需要两个数来进行操作,在二进制表示中每一位相对应的都为1的时候才能为1 ,例如: 12 & 7 = 4 ,运算的办法见下图
2, |或与运算
或与运算也是一个二元运算符,我们在二进制中操作的时候。只要当前位置上存在一个 1 的结点我们运算之后的结果就会存在这个1 ,实际上我们就能使用 我们在语法中所学习的 || 来进行理解。同样的例子: ** 13 | 7 == 15 **
3,^异或运算
异或运算还是一个二元运算符,当同一个位置的两组数据分别为1 和 0 的时候我们就取1 ,当他全为 0 或者 1的时候我们取值为 0 ;
4,~按位取反(考察少)
一元运算符,我们进行相关的直接取反的操作就是每一位位置都取反,相关的我们知知道就是数据类型分成int 和**long long ** 的数据类型,当然在我们代码操作中
#include <iostream>
using namesapce std ;
int main ()
{
int n ;
cin >> n ;
cout << ~n << endl;
return 0;
通常情况下 , ~n == -(n + 1 )
二,位运算中的常见操作
位运算题型中有明显的二进制问题还有一些比较隐蔽的问题,我们把位运算问题分为明显二进制和隐蔽问题两类
1,二进制问题
1,位1个数(把数转化成二进制之后,我们有几位是1)
算法思路:
- n - 1 和 n 的二进制位的特性问题:n 在减 1 操作之后只有最靠近右侧的1变成0 ,1右侧的0会变成 1
2.n和n - 1 的 & 运算的特性
例题: 13有几个1 ?
操作如下。
#include <iostream>
using namespace std ;
int cnt = 0 ;
int main ()
{
int n ;
cin >> n ;
while (n)
{
n = n & (n - 1) ;
cnt ++ ;
}
cout << cnt << endl ;
return 0 ;
}
2,在二进制中是否是是交错的(10101010)
算法思路:
1,每次都判断后两位: &3 娶到后两位的值
2,每次都让序列向后面走一个 >>=
代码
#include <iostream>
using namespace std ;
int main ()
{
int n ;
cin >> n ;
while (n)
{
if ((n & 3 )== 3 || (n & 3 )== 0)
{cout << "no" ;return 0 ;}
n >>= 1;
}
cout << "Yes" <<endl ;
return 0 ;
}
3,汉明距离(分析两个数二进制中不同的数位的数量)
首先我们异或运算得出一个每一个1都代表着不同的操作,再完成对1的统计。
2,常规问题
1,N是不是2的幂,2的奇次幂,2的偶次幂
算法思路
数学知识:2的幂在二进制中的表示为,有且仅有一个位子上为1,并且这个数大于 0,我们只用证明这个数的1的位数为1就可以;
2的偶数幂就要控制一下这个1的位置,我们使用取模的方法来求解 n % 3 == 1 ;2的奇数幂也由于可以使用 n % 3 = = 2 的办法求解
取1的位数的基本运算
#include <iostream>
using namespace std ;
int main ()
{
int n ;
cin >> n ;
if((n & (n - 1)) == 0 && n > 0)
cout << n << "is 2 ^" << endl ;
else cout << "No" << endl ;
return 0 ;
}
2,判断只出现一次的值,其他的值都出现偶数次
使用^操作符,当出现使用特性 n ^ n = 0 , n ^ 0 = n;
#include <iostream>
using namespace std ;
int main ()
{
int n ;
cin >> n ;
int x ;
int ans = 0;
for(int i = 0 ; i < n ; i++ )
cin >>x , ans ^= x ;
cout<<x << endl ;
return 0 ;
}
3,交换数字
交换数字使用的是异或运算中的三角性关系,
我们可以看一道例题:a= 7 ,b = 13交换
#include<iostream>
using namespace std ;
int main ()
{
int a,b ;
cin >> a,b ;
a= a^b ;
b =a^b;
a = a^b ;
return 0 ;
}