位运算位与

article/2025/8/27 10:15:30

目录

一、知识点

1.位与的定义

2.简单应用

(1)奇偶性判定

(2)取末五位

   (3)消除末尾五位

(4)2的幂判定

 二、习题

1.191. 位1的个数 - 力扣(LeetCode)

2.剑指 Offer 15. 二进制中1的个数 - 力扣(LeetCode)

3. 1356. 根据数字二进制下 1 的数目排序 - 力扣(LeetCode)

4.762. 二进制表示中质数个计算置位 - 力扣(LeetCode)

5.231. 2 的幂 - 力扣(LeetCode)

 6.397. 整数替换 - 力扣(LeetCode)

7.1404. 将二进制表示减到 1 的步骤数 - 力扣(LeetCode)


一、知识点

1.位与的定义

 位与运算符有两个操作数,表示为 x & y

对操作数的每一位进行运算,都是1的时候结果为1,否则为0

左操作数右操作数结果
000
010
100
111

举例:0b1010&0b0110=0b0010;(0b为二进制数前缀)

(printf设置输出结果%d为十进制数2)

2.简单应用

(1)奇偶性判定

if(5%2==1)
{cout<<"5是奇数";}if(5&1)              //5&1==1
{cout<<"5是奇数";}if(8&1==0)              
{cout<<"8是偶数";}

偶数二进制末位为0,奇数二进制末位为1。

偶数&1为0,奇数&1为1,即可判断。

(2)取末五位

//给定一个数,求它的二进制表示的末五位,以十进制输出即可。#include<iostream>
using namespace std;
int main()
{int x;cin>>x;cout<<(x&0b11111)<<endl;return 0;
}

问题核心:我们只需要末五位,剩下的位不需要,所以将给定的数 位与 0b11111 ,这样可以直接得到末五位的值,因为11111再高位为0,不管是0还是1 位与 0 都是0, 即可将高位抹去,而末五位,0&1=0,1&1=1,也就是说末五位 位与 11111的结果是不变的,仍然是末五位。

 (3)消除末尾五位

给定一个32位整数,要求消除它的末五位。

      消除末五位,即将末五位变成0,保留剩下的位

      将这个数与0b 11111111111111111111111111100000 (转换成十六进制为0xffffffe0)位与。

x&0b11111111111111111111111111100000 与 x&0xffffffe0 同理。

(4)2的幂判定

判断一个整数是不是2的幂

 如果一个数是2的幂,它的二进制必然为 100……00 形式。(有k个0)这个数的十进制为2^{k}

将其减一,二进制表示为011……11形式(有k个1)(可根据等比数列的和的公式来推导)

这两个数位与为0,

所以一个数x是2的幂,那么x&(x-1)必然为0。

(x&(x-1))==0

 二、习题

1.191. 位1的个数 - 力扣(LeetCode)

class Solution {
public:int hammingWeight(uint32_t n) {int sum=0;
while(n)
{
n&=(n-1); 
sum++;
}return sum; }
};
//若一个数末尾有k个0(末尾的前面是1:100……00),将它减1,错位可得k个1(前面为0:011……11) 两者位运算得到k+1个0,将数的最低位1去掉。
//n & (n-1) 实现:将n的二进制最低位的1去掉,去掉多少次,就有多少1。
//若末尾为1,它减1,末尾为0,其他位数一样,两者位与,1仍然消去仍然可以n&(n-1)

2.剑指 Offer 15. 二进制中1的个数 - 力扣(LeetCode)

与1同理。

3. 1356. 根据数字二进制下 1 的数目排序 - 力扣(LeetCode)

题目:给你一个整数数组 arr 。请你将数组中的元素按照其二进制表示中数字 1 的数目升序排序。

           如果存在多个数字二进制中 1 的数目相同,则必须将它们按照数值大小升序排列。

           请你返回排序后的数组。
 

class Solution {
public:
int bitcount(int n)   //1的数目
{
int sum=0;
while(n)
{
n&=(n-1);
sum++;
}
return sum;
}vector<int> sortByBits(vector<int>& arr) {for(int i=0;i<arr.size();i++)
{
arr[i]+=bitcount(arr[i])*100000;   //arr里所有数值更新为  它本身 + 1的数目*100000(不能是10000,因为10000%10000为0,只要是大于10^5的数里面只有一个1就行1000000也可以),给这个数升序,即满足题意。题目先根据1的数目排序,所以数目乘以100000,这个是排序第一个要考虑的,最高位的值,然后若1的数目一样,再根据数值本身,这样  arr[i] + 1的数目*100000 即满足条件。
}//造出 「1的个数 * 100000 + 原数字」的数字来排序。即高位数字表示1的个数,低位数字表示原数字。sort(arr.begin(),arr.end());   //arr数组升序。for(int i=0;i<arr.size();i++)
{
arr[i]%=100000;//最后将高位都去掉,留下arr[i]最初本身的数值。
}
return arr;}
};

4.762. 二进制表示中质数个计算置位 - 力扣(LeetCode)

        给你两个整数 left 和 right ,在闭区间 [left, right] 范围内,统计并返回 计算置位位数为质数 的整数个数。

        计算置位位数 就是二进制表示中 1 的个数。

        例如, 21 的二进制表示 10101 有 3 个计算置位。

class Solution {
public://是否为质数。
bool isprime(int n)
{if(n<2)return false;
for(int i=2;i<=sqrt(n);i++)
{
if(n%i==0)
return false;
}
return true;
}//数位中1的个数。这里面i数值的改变不影响for循环里,范围在left~right里的i的数值。 这个函数的代码若写在for里面,一定要注意i的值是改变的,应该要初始化一个中间变量,比如mid=i,来代替i判断i的个数是否为质数。
int bitcount(int i) 
{int num=0;
while(i)
{i&=(i-1);num++;//num为1的个数。
}
return num;
}int countPrimeSetBits(int left, int right) {
int sum=0,num;
for(int i=left;i<=right;i++)
{//判断num是否为质数。
if(isprime(bitcount(i))) //判断1的个数是否为质数。
sum++;
}return sum;}
};

5.231. 2 的幂 - 力扣(LeetCode)

class Solution {
public:bool isPowerOfTwo(int n) {
if(n<=0)
return false;if((n&(n-1))==0)
return true;return false;}
};

 6.397. 整数替换 - 力扣(LeetCode)

给定一个正整数 n ,你可以做如下操作:

如果 n 是偶数,则用 n / 2替换 n 。
如果 n 是奇数,则可以用 n + 1或n - 1替换 n 。
返回 n 变为 1 所需的 最小替换次数 。

class Solution {
public:int integerReplacement(int n) {if(n==1)return 0;if(n%2==0)return 1+integerReplacement(n/2); 
//1步,n/=2return 2+min(integerReplacement(n/2),integerReplacement(n/2+1)); 
//两步,因为一个奇数+1,-1之后肯定要除以2, 
//n的最大值为2^31-1,若+1,则溢出,所以先对n除以2,再+1,
//floor(n/2)+1 等效于 (n+1)/2    floor(n/2) 等效于 (n-1)/2   floor为向下取整。}
};


http://chatgpt.dhexx.cn/article/tFxViaQi.shtml

相关文章

位与、位或、异或、位移运算

位与&#xff08;&&#xff09; 参与运算的两个数据&#xff0c;按照二进制位进行“与运算”。运算规则&#xff1a;0&00; 0&10; 1&00; 1&11; 即&#xff1a;两位同时为1&#xff0c;则值为1。否则为0 例如&#xff1a;9 & 5 1001 & 010…

git操作--------------------------------拉取某个远程分支到本地

1.新建一个空文件夹 例如:test 2.右键选择git bash here 初始化: git init可以看到文件夹里多了个.git隐藏文件 3.与远程master分支建立连接 git remote add origin http://xxx.xxx.xxx.xxx:xx/ly/fafafa.git直接去复制git仓库连接就行,这里以http做的示例 4.将远程分支拉到…

git远程分支代码拉取

1.远程拉取gitlab 工程分支&#xff0c;并在本地建立分支 具体过程 新建一个空文件初始化 git init自己要与origin master建立连接&#xff08;下划线远程仓库链接&#xff09; git remote add origin http://192.168.9.10:8888/root/game-of-life.git把远程分支拉到本地&#…

JAVA语言(Git拉取远程分支(dev)到本地)

步骤&#xff1a; 1、新建一个空文件&#xff0c;文件名为yrc_20220126 2.在当前文件夹单机鼠标右键&#xff0c;效果如下图&#xff1a; 3.点击弹出窗口的&#xff1a;Git Bash Here 4、初始化 git init5、自己要与origin master建立连接&#xff08;下划线为远程仓库链接…

idea把git远程分支拉取到本地

在开发过程中&#xff0c;我们有时候会碰到一种情况&#xff1a; 本地分支只有 development&#xff0c;远程分支有development,release,master这三个分支&#xff0c;那么我们本地要怎么切换到master分支呢&#xff1f; 一&#xff1a;正常来说&#xff0c;直接在idea的右下角…

git拉取远程指定分支到本地(本地分支映射到远程分支)

git拉取远程分支到本地 step1:新建一个空文件夹&#xff0c;名wuliu step2:初始化git git initstep3:与远程仓库建立连接 git remote add origin http://git.xxx.com:10001/root/vue-upms.git![在这里插入图片描述](https://img-blog.csdnimg.cn/20191008132344130.png st…

Git拉取远程分支到本地,修改并同步

Git拉取远程分支到本地 本地新建一个空白文件夹folder&#xff1b;进入folder目录&#xff0c;打开git bash&#xff0c;用命令行初始化git仓库&#xff1b; $ git init与远程仓库建立连接&#xff1b; // http://xxx...该网址为远程仓库Game的ip地址&#xff0c;可在远程仓…

从Git上如何拉取远程分支(dev)到本地?

步骤 1. 首先新建一个空的文件&#xff0c;文件名自定义2. 在当前文件夹下鼠标右击打开Git Bash here3. 打开后进行初始化 &#xff1a; git init4. 与origin master建立一个连接5. 把远程分支拉到本地6. 在本地创建分支dev并且进行切换到该分支7. 把某个分支上的内容进行拉取到…

【git之路】拉取远程分支到本地

文章目录 1、新建一个空文件夹2、初始化3、自己要与origin master建立连接&#xff08;下划线为远程仓库链接&#xff09;4、把远程分支拉到本地5、在本地创建分支dev并切换到该分支6、把某个分支上的内容都拉取到本地检查下&#xff0c;就结束啦 1、新建一个空文件夹 取名mas…

git 拉取远程分支到本地及本地切换分支

拉取远程分支到本地及本地切换分支 涉及的操作内容1.远程代码拉取到本地 - 2.本地合并其它分支代码 - 3.本地代码提交到远程指定仓库 - 4.本地切换分支 1.远程代码拉取到本地 首先确定要切换分支&#xff0c;查看当前本地及远程所有分支 git branch -a红色为远程分支&#…

git拉取远程分支到本地

**步骤&#xff1a; 1、新建一个空文件&#xff0c;文件名为hhhh 2、初始化 git init 3、自己要与origin master建立连接&#xff08;下划线为远程仓库链接&#xff09; git remote add origin gitgithub.com:XXXX/nothing2.git 远程仓库链接在github这里&#xff0c;如下…

git 拉取远程分支到本地(最简单方式)

步骤&#xff1a; 接下来我们进入正题&#xff1a; 一、新建一个空文件&#xff0c;文件名为hash------(名字随便取&#xff09; 二、初始化------git init 注意–(初始化完成之后记得检查文件夹是否有**(.git文件夹&#xff09;**-----有些文件夹打开没有大多数是隐藏了&am…

git拉取远程指定分支到本地

1.通过git clone的方式 只克隆单一分支&#xff1a; git clone -b <branch> --single-branch <url>注意&#xff1a; git clone -b <branch> <url>这条克隆的指令与全克隆的作用一致。 2.通过本地分支映射到远程分支的方式 a.与远程仓库建立连接 …

git 拉取远程分支到本地

目录&#xff1a; ***&#xff01;本小作者&#xff0c;是将终端和Git的可视化插件结合使用&#xff0c;刚接触的可以自习看一下&#xff0c;内容简单&#xff0c;避免弯路&#xff01;***一&#xff0c;简单了解远程分支1&#xff0c;连接远程&#xff1a;2&#xff0c;提交&a…

socket协议解读

前言 Socket的使用在 Android网络编程中非常重要今天我将带大家全面了解 Socket 及 其使用方法 目录 1.网络基础 1.1 计算机网络分层 计算机网络分为五层&#xff1a;物理层、数据链路层、网络层、运输层、应用层 其中&#xff1a; 网络层&#xff1a;负责根据IP找到目的地址的…

UDP/IP传输协议

一、传输层最重要的协议就是TCP和UDP。TCP协议复杂&#xff0c;是面向连接的传输协议且传输可靠&#xff1b;而UDP协议简单&#xff0c;是面向无连接的传输协议&#xff0c;传输速度快但传输不可靠。可以将UDP协议看作IP协议暴露在传输层的一个接口。 UDP协议同样以数据报(dat…

基于TCP协议的Socket网络通信

前言 一. 什么是网络(了解七层网络模型)?二. 什么是TCP/UDP协议?三.什么是socket?定义 四.基于TCP协议的socket通信的实现步骤是怎样的&#xff1f;客户端的实现服务端的实现测试 一. 什么是网络(了解七层网络模型)? 按区域可分为&#xff1a; 局域网&#xff08;区域小&am…

socket、tcp/ip、http三者之间的区别和原理

网络七层模型 OSI 模型(Open System Interconnection model)是计算机和网络在世界范围内实现互联的标准框架。它将计算机网络体系结构划分为七层,每层都可以提供抽象良好的接口。 1、物理层&#xff1a;例如线路、无线电、光纤、信鸽 物理层负责最后将信息编码成电流脉冲或其…

简单理解socket协议

TCP/IP 要想理解socket首先得熟悉一下TCP/IP协议族&#xff0c; TCP/IP&#xff08;Transmission Control Protocol/Internet Protocol&#xff09;即传输控制协议/网间协议&#xff0c;定义了主机如何连入因特网及数据如何再它们之间传输的标准&#xff0c; 从字面意思来看T…

Http、TCP/IP协议与Socket之间的区别

HTTP协议&#xff1a;简单对象访问协议&#xff0c;对应于应用层 &#xff0c;HTTP协议是基于TCP连接的 tcp协议&#xff1a; 对应于传输层 ip协议&#xff1a; 对应于网络层 TCP/IP是传输层协议&#xff0c;主要解决数据如何在网络中传输&#xff1b;而HTTP是应用层协…