位运算基本内容与例题

位运算基本内容与例题

在这里插入图片描述

Leetcode 201 数字范围按位与

201. 数字范围按位与

思路1

我们求 & 运算,最开始想到的暴力方法,将每个数字与运算过一遍

示例1:

ans = 5 & 6 & 7

code

int bit(int m , int n )
{
	int result = m; 
    for(int i = m + 1 ; i <= n ; i++ )
    {
        result = result & i;
    }
    return result;
}

注意result初始化为m,而不是0,想想为什么?

因为如果设置

result = 0;
 0 & i = 0; // 0 & 任何东西都 = 0

不过该方法超时…

思路2

我们假设两个二进制

m: 1001 0110
n: 1001 1010 //m < n 

可以发现m -> n的所有数 ,前四位都是不变的

而后四位发生变化

所以我们从开始不同相同的地方 设为分界点

m: 1001 | 0110
n: 1001 | 1010 				//m < n

所以就必定有

m : 0 xxxxxxx
n : 1 xxxxxxx

由 [m,n] 区间 一定存在

m : 0 1111
n : 1 0000  // 极端情况 m = 0 1111 n = 1 0000

**所以 m & n = 0 **

**这之后就全是0!!( 0 & 啥) == 0 **

所以,我们最后只需要找到

m 和 n 开始相同的位就可以了!!

code

int rangeBitwiseAnd(int m, int n){
	int count = 0 ; //记录位置
	while( m != n )
	{
		m >>= 1;
		n >>= 1; // 找到m == n 的位
		count++;
	}
	return m << count; //左移补0
}

end…

位运算的内容

& 、 | 、 ^ 、>> 、 << 、~

1、与运算&

​ 1)两个都是1,结果才是1

​ 2)可以用来判断奇偶

if( ( a & 1 ) == 1 ) 

if( ( a % 2 == 0 ))
//两句等效

​ 3)取指定位置的数

	1111 0110 //取后四位
&	0000 1111
______________
	0000 0110
//与运算取得后四位
2、或运算 |

​ 1)两个0,才是0

​ 2)设置为1/0

//后四位设置为1
	1101 0101
| 	0000 1111
______________
	1101 1111
//设置为1
3、异或运算 ^

​ 1)

0^0 =0  0^1=1  1^0=1  1^1=0  a^a = 0  a^0 = a

​ 2)无中间变量交换两个数

int a = 1 ;
int b = 2;
a = a^b;  	//a = a^b   b = b 
b = a^b;	//a = a^b	b = a^b^b , 由上面的性质b^b = 0 -> b = a^0 = a;
a = a^b;	//a = a^b^a ,同上 a = b , b = a;

3)查找一堆数里面一个数出现了奇数次,其他数出现了偶数次,这个奇数次的是啥

int eor = 0;
int a[i] = { 5 , 1 ,2 ,3, 4, 4, 5 ,2 , 1};
for(int i = 0 ; i < sizeof(a) / sizeof(int) ; i++ )
{
	eor ^= a[i];
}
printf("%d",eor);
//eor = 3

4)取出二进制中最右侧的1

N    = 0011 0101 1100
~N   = 1100 1010 0011
~N+1 = 1100 1010 0100

//N&(~N + 1 )  ---> 0000 0000 0100

5)二进制里有几个1

int N = 16;
int count = 0;
while( N != 0 )
{
	int right = N & (~N + 1);
	count++;
	N ^= right; //异或掉,都是1 ,则最右侧的1->0;
}
4、取反~
~1 = 0 
~0 = 1
5、右移>>

将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃

1110 0011
// a >>= 1; 
1111 0001
6、左移<<

将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)

1010 1110
// a = a << 2;
1011 1000
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值