位运算总结(一)

位运算

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。
注意:位运算是针对二进制的运算,所以手动模拟时要先将数转化为二进制。

常见的位运算

按位与a&b
按位或a|b
按位异或a^b
按位取反~a
左移a<<b
带符号右移a>>b

1、按位与

同位上,有0则0,同1则1;
a: 19    b: 10    a&b: 2
为方便表示以下每个数只写8位

a00010011
b00001010
a&b00000010

2、按位或

同位上,有1则1,同0则0;
a: 19    b: 10    a|b: 27

a00010011
b00001010
a|b00011011

3、按位异或

同位上,相同为0,不同为1;
a: 19    b: 10    a^b: 25

a00010011
b00001010
a^b00011001

4、按位取反

每一位,1变0,0变1;
a: 19    ~a: -20
(如果不懂负数的二进制表示看这里)

a00010011
~a11101100

5、左移

每一位左移,右边补零;
a: 19    a<<1: 38    a<<2: 76

a00010011
a<<100100110
a<<201001100

6、带符号右移

每一位右移,左边补充最高位数(正数补1,负数补0);

正数

a: 19    a>>1: 9    a>>2: 4

a00010011
a<<100001001
a<<2000000100
负数

a: -19    a>>1: -10    a>>2: -5

a11101101
a<<111110110
a<<211111011

代码

	int a=19,b=10;
	cout<<"a:19  	b:10     a&b: "<< (a&b) <<endl;
	cout<<"a:19  	b:10     a|b: "<< (a|b) <<endl;
	cout<<"a:19  	b:10     a^b: "<< (a^b) <<endl;
	cout<<"a:19  	~a  :"<< (~a) <<endl;
	cout<<"a:19   	a<<1:"<< (a<<1) <<"   a<<2:"<< (a<<2) <<endl;
	cout<<"a:19   	a>>1:"<< (a>>1) <<"    a>>2:"<< (a>>2) <<endl;
	a=-19;
	cout<<"a:-19  	a>>1:"<< (a>>1) <<"  a>>2:"<< (a>>2) <<endl;

输出

在这里插入图片描述

位运算应用

Acwing 801.二进制中一的个数

原题链接:Acwing 801.二进制中一的个数

题目描述

给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 1 的个数。

输入格式

第一行包含整数 n。

第二行包含 n 个整数,表示整个数列。

输出格式

共一行,包含 n 个整数,其中的第 i 个数表示数列中的第 i 个数的二进制表示中 1 的个数。

数据范围

1≤n≤100000,
0≤数列中元素的值≤109

输入样例

5
1 2 3 4 5

输出样例

1 1 2 1 2

代码

解法1 yxc’s

#include<iostream>

using namespace std;

int lowbit(int x)
{
	return x&-x; 
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n;
	cin>>n;
	while(n--)
	{
		int x;
		cin>>x;
		int res=0;
		while(x)	x-=lowbit(x),res++;
		cout<<res<<' ';
	}
	return 0;
 } 

解法2

#include<bits/stdc++.h>
using namespace std;

void solve()
{
    int n;
    cin>>n;
    while(n--)
    {
        int x;
        cin>>x;
        
        int res=0;
        while(x)
        {
            if(x&1) res++;
            x=x>>1;
        }
        cout<<res<<" ";
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    solve();
    return 0;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值