【C语言】位操作符的一些题目与技巧

news2025/1/12 3:03:12

初学者在学完位操作符之后,总是不能很好的掌握,因此这篇文章旨在巩固对位操作符的理解与使用。
有的题目可能会比较难以接受,但是看完一定会有收获

目录

  • 位操作符:
  • 一些题目:
    • 不创建临时变量交换整数
    • 整数转换
    • 二进制中1的个数
    • 不用加减乘除实现加法
    • 寻找奇数
    • 错误的集合(必看)
  • 小技巧:
  • 总结:

位操作符:

开始之前,先来了解一下位操作符

&按位与,只有两个数同时为真才为真,否则为假
| 按位或,只有两个数同时为假才为假,否则为真
^按位异或,两个数相同为0,不同为0

例子:
按位与:
在这里插入图片描述
按位或:
在这里插入图片描述
按位异或:
在这里插入图片描述

一些题目:

题目大都来自牛客与力扣,虽然不能很好的囊括位操作符的全部,但是可以很好的加深理解。

一一一一一一一一一一一一一一分割线一一一一一一一一一一一一一一

不创建临时变量交换整数

注意:此题无链接

不能创建临时变量(第三个变量),实现两个数的交换。
a=10b=20

做这题首先要知道:

位操作符支持交换律
num^num=00^num=num
那么我们就可以解决这道题

先来看代码实现,方便理解思路

代码实现:

#include <stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    a = a^b;
    b = a^b;
    a = a^b;
    printf("a = %d b = %d\n", a, b);
    return 0;
}

思路:

a = a^b的a带入b = a^b中的a,即b=a^b^b,则b=10
b = a^b的b带入a =a^b中的b,即a=a^a^b,则a=20

一一一一一一一一一一一一一一分割线一一一一一一一一一一一一一一

整数转换

整数转换,链接奉上
在这里插入图片描述
思路:

首先我们要知道,num & 1为最后一位二进制的数字,
那我们使用移位操作符遍历一下整数的32位比特位就迎刃而解

代码实现:

int convertInteger(int A, int B)
{
    int count=0;//创建计数器
    int i=0;
    for(i=0;i<32;i++)
    {
        if((A>>i&1)!=(B>>i&1))
        count++;
    }
   return count;   
}

一一一一一一一一一一一一一一分割线一一一一一一一一一一一一一一

二进制中1的个数

注意:此题无链接
在这里插入图片描述

这题和上一题大同小异,都可以使用位移操作符与位操作符遍历解决,但这种方法必须循环32次(整形情况下)才能得到结果

还有一种方法:

使用num&(num-1),这个式子的意义是什么呢?
是将式子最右边的1消掉

举个例子:

while(num)
{
   num&(num-1);
}
//假设在while循环中,设num为15,那么二进制就为1111
   1111 num
   1110 num-1
   1110 新的num
   1101 num-1
   1100 新的num
   1011 num-1
   1000 新的num
   0111 num-1
   0000 新的num

可以看到,当num为0时循环停止,循环了4次,也就是1的个数

我们就可以使用这种方法做题

思路:

使用num&(num-1)计算二进制1的个数

代码实现:

#include <stdio.h>
int main()
{
    int num = -1;
    int i = 0;
    int count = 0;//计数
    while(num)
    {
        count++;
        num = num&(num-1);
    }
    printf("二进制中1的个数 = %d\n",count);
    return 0;
}

一一一一一一一一一一一一一一分割线一一一一一一一一一一一一一一

不用加减乘除实现加法

不用加减乘除做加法,链接奉上
在这里插入图片描述

按位异或其实有个别名,叫做不进位加法,什么意思呢?
就是可以计算不进位的加法
例如:

int a=10;
//0000 1010
int b=20;
//0001 0100
int sum=a^b;
//0001 1110也就是30,
//我们发现当没有进位时,按位异或可以代替加法,那么有进位怎么办呢?

不过我们要想解决这个题,仅仅知道不进位加法是不够的,
我们从10进制举例
计算12+9

1.1+0=0,2+9=1(先不计算进位),结果为11
2.2+9有进位,进位为10
3.两者相加:10+11=21

既然如此,我们也可以利用这种方法计算,那进位如何表示呢?
二进制中只有两个1才会进位,因此我们按位与两个要相加的数,再进行左移就可以模拟进位。

思路:

1.将两个要相加的数字按位异或
2.将两个数字进行按位与并向左移1位计算出进位
3.将两数相加,此时只需重复上述两个步骤,直到进位为0。

代码实现:

int Add(int num1, int num2 ) 
{
    int sum=0;
    int forward=0;
    do
    {
        sum=num1^num2;
        forward=(num1&num2)<<1;
        num1=sum;//num1与num2顺序不重要
        num2=forward;
    }while(forward);
    return sum; 
}

一一一一一一一一一一一一一一分割线一一一一一一一一一一一一一一

寻找奇数

寻找奇数,链接奉上
在这里插入图片描述
思路:

在不创建临时变量交换整数,
我们了解了num^num=00^num=num,那我们这题就可以使用这种方法

#include <stdio.h>
#include<stdlib.h>

int main() 
{
    int n=0;
    scanf("%d",&n);
    int arr[n];
    //由编译器决定是否支持加长数组,
    //牛客网支持,也可以不使用加长数组
    //根据题目条件选择合适的个数范围
    int ans=0;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&arr[i]);
        ans^=arr[i];
    }
    printf("%d",ans);
    return 0;
}

一一一一一一一一一一一一一一分割线一一一一一一一一一一一一一一

错误的集合(必看)

错误的集合,链接奉上
在这里插入图片描述
思路:
我们发现,重复的数字与消失的数字出现的次数都是偶数次(2和0次),其他的数字出现次数是奇数次(1次),此时我们可以多添加一个从1~n正确的数字集合,使重复的数字与缺失的数字为奇数次(3和1次),其他的数字出现次数为偶数次(2次),我们利用异或就可以比较好的解决
x,y分别为重复的数字与消失的数字,将2n个数字按位异或在一起,因为num^num=00^num=num,结果为x^y,我们记为xor
因为x!=y,故xor不为0,我们此时令lowbit=xor&(-xor),这是为了取得x与y最低位不同比特位(其实只要是不同的就可以,只是最低位好获得),简单的解释一下:

当x与y有最低位bit位不同时时,当前位异或的结果为1,那我们如何找到这个1呢
使用lowbit=xor&(-xor)
例如:
0000 1010 10的补码
1111 0110 -10的补码
0000 0010 按位与得到最低位不同比特位

得到lowbit后,将2n个数字分成两组,第一组每个数字a都满足a&lowbit==0,第二组每个数字b满足b&lowbit!=0
创建个2个变量,num1与num2,将第一组的a按位与在一起赋值给num1,另一组同样赋值给num2,此时num1与num2就是x或y,因为相同的数字肯定在一组,并且除了x与y出现的次数都是偶数次,故得到num1与num2就是x或y
此时将x与nums数组遍历比较一遍,如果出现即为消失的数字,否则相反。
代码实现:

int* findErrorNums(int* nums, int numsSize, int* returnSize) 
{
    static int arr[2];
    int xor=0;
    for(int i=1;i<=numsSize;i++)
    {
        xor^=nums[i-1];
        xor^=i;
    }
    //得到x^y
    int lowbit=xor&(-xor);
    //得到最低位比特位
    int num1=0;
    int num2=0;
    for(int i=0;i<numsSize;i++)//分组nums数组
    {
        if((nums[i]&lowbit)==0)
        num1^=nums[i];
        else
        num2^=nums[i];
    }
    for(int i=1;i<=numsSize;i++)//分组添加的数字
    {
        if((i&lowbit)==0)
        num1^=i;
        else
        num2^=i;
    }
    int count=0;//计数器
    int i=0;
    for(i=0;i<numsSize;i++)
    {
        if(nums[i]==num1)
        count++;
    }
    if(count==0)
    {
    arr[1]=num1;
    arr[0]=num2;
    }
    else
    {
    arr[1]=num2;
    arr[0]=num1;
    }
    *returnSize=2;
    return arr;
}

小技巧:

一些位运算中的简便运算

1.x & 1 是奇数返回1,是偶数返回零,可以放在if中判断奇偶
2. x |= 1<<j 等价于 x += pow(2,j);
3.x<<2 x<<1,在十进制中表现的是乘上2的多少次方,在二进制中,就是先将这个x转换为二进制,然后整个数往前移位。(最后转化回去还是一样的)
4.num^num=00^num=num,异或也叫xor

总结:

在遇到数字重复时,二进制时,计算时,可能会有操作符的做法
遇到不会做的题很正常,不要感到沮丧,要知道我们也是站在巨人的肩膀上才能看得更远

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/938662.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【校招VIP】产品设计分析之思维整体性

考点介绍&#xff1a; 对于产品分析设计时需要全面的分析用户需求&#xff0c;而产品思维方式的核心是“以问题为核心”&#xff0c;即先多花时间搞清楚要解决的问题究竟是什么&#xff0c;要深入、全面的思考。 『产品设计分析之思维整体性』相关题目及解析内容可点击文章末尾…

揭秘偏向锁的升级

今天开始&#xff0c;我会和大家一起深入学习synchronized的原理&#xff0c;原理部分会涉及到两篇&#xff1a; 偏向锁升级到轻量级锁的过程轻量级锁升级到重量级锁的过程 今天我们先来学习偏向锁升级到轻量级锁的过程。因为涉及到大量HotSpot源码&#xff0c;会有单独的一篇…

从钉钉到金蝶云星空通过接口配置打通数据

从钉钉到金蝶云星空通过接口配置打通数据 对接系统钉钉 钉钉&#xff08;DingTalk&#xff09;是阿里巴巴集团打造的企业级智能移动办公平台&#xff0c;是数字经济时代的企业组织协同办公和应用开发平台。钉钉将IM即时沟通、钉钉文档、钉闪会、钉盘、Teambition、OA审批、智能…

python | 将pdf文件转换为图片,这一招就够了

一、背景 部分情况下&#xff0c;需要将 PDF 页面转换为图片&#xff0c;例如 PNG 或 JPEG 格式。 python 的开源库 pdfplumber&#xff0c;提供了将 pdf 文件转换为图片的方法。 如果之前还没有安装和使用过pdfplumber库&#xff0c;pdfplumber的安装及基础使用&#xff0c;可…

【React学习】—SetState的使用(九)

【React学习】—SetState的使用&#xff08;九&#xff09; state的简写方式 state属性总结

PCD格式点云文件结构及在线查看工具

本文档描述了 PCD&#xff08;点云数据&#xff09;文件格式及其在点云库&#xff08;PCL&#xff09;中的使用方式。可以使用NSDT 3DConvert 在线预览查看PCD格式的点云数据文件。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 1、为何定义新的点云数据文件格式&#…

【问题总结+备忘录】上传一个shp文件能够读取其中的空间矢量字段,代码+采坑总结

需求描述 要求上传一个shp文件能够读取其中的空间矢量字段。 简单分析 SHP上传格式应该有两种&#xff08;zip格式和.shp的格式文件内部可能存在多个空间矢量&#xff0c;结果以列表形式返回文件不大&#xff0c;使用MultipartFile上传上传即可结合geo-tools读取空间字段&am…

【C++进阶(二)】STL大法--vector的深度剖析以及模拟实现

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; vector 1. 前言2. 熟悉vector的接口函数2.1 vec…

无涯教程-Python机器学习 - Reinforcement Learning函数

这些方法不同于以前研究的方法,也很少使用。在这种学习算法中,我们需要在一段时间内训练一个代理,以便它可以与特定环境交互。代理将遵循一系列与环境进行交互的策略,然后在观察环境之后,它将针对环境的当前状态采取措施。以下是强化学习方法的主要步骤。 第1步-首先,我们需要准…

金鸣表格文字识别软件,让你的图片瞬间变成excel

来百度APP畅享高清图片 首先&#xff0c;让我们打开金鸣表格文字识别软件&#xff01; 然后点击那个“添加文件”的按钮&#xff0c;在弹出的窗口中选择你想要识别的图片&#xff0c;再点击“打开”&#xff0c;就可以把图片添加到待识别的列表中了。 接下来&#xff0c;你只需…

领星ERP和金蝶云星空接口打通对接实战

领星ERP和金蝶云星空接口打通对接实战 对接系统&#xff1a;领星ERP 深圳市领星网络科技有限公司创立于2017年&#xff0c;致力于通过SaaSERP产品为跨境电商行业创造价值&#xff0c;让跨境生意更简单。公司总部位于深圳&#xff0c;在广州、杭州、厦门等设有服务中心。领星现已…

[计算机入门] 账户管理

3.4 账户管理 用户账户是计算机操作系统中用于标识和管理用户身份的概念。 每个用户都拥有一个唯一的用户账户&#xff0c;该账户包含用户的登录名、密码和其他与用户身份相关的信息。 用户账户通常用于验证用户身份&#xff0c;并授权对系统资源的访问权限。在多用户操作系统…

SSL证书申请

DV SSL证书申请需要多久&#xff1f; DV SSL证书无需验证所有者资质资料&#xff0c;审核流程相对简单&#xff0c;因此可快速签发。但部分域名信息可能会触发不同等级的安全审查机制&#xff0c;必要时需要人工介入进行审查签发&#xff0c;因此&#xff0c;SSL证书签发时间可…

【OpenCV • c++】图像对比度调整 | 图像亮度调整

&#x1f680; 个人简介&#xff1a;CSDN「博客新星」TOP 10 &#xff0c; C/C 领域新星创作者&#x1f49f; 作 者&#xff1a;锡兰_CC ❣️&#x1f4dd; 专 栏&#xff1a;【OpenCV • c】计算机视觉&#x1f308; 若有帮助&#xff0c;还请关注➕点赞➕收藏&#xff…

GIS全国技能大赛试题及解题过程

1、提供数据列表如下&#xff1a; 2、试题要求如下&#xff1a; 3、解题步骤如下&#xff1a; &#xff08;1.1&#xff09;导入土地利用数据&#xff0c;如下&#xff1a; &#xff08;1.2&#xff09;导入土地采集表格&#xff0c;然后右键选择显示XY数据&#xff0c;如下&am…

python二维索引转一维索引 多维索引转一维索引

将二维索引转为1维索引 原博客地址&#xff1a;https://blog.csdn.net/qq_42424677/article/details/123011642 将n维索引映射成1维索引 def ravel_index(x, dims):i 0for dim, j in zip(dims, x):i * dimi jreturn i

Cesium 叠加天地图-中国近海海洋等深面图层服务

Cesium 叠加天地图-中国近海海洋等深面图层服务 核心代码完整代码&#xff1a;在线示例 偶然发现天地图有一个近海海洋图层&#xff0c;觉得不错&#xff0c;于是尝试叠加一下&#xff0c;花费了一些时间&#xff0c;叠加成功&#xff0c;这里分享一下。 本文包括核心代码、完…

Google Zxing依赖在linux服务器上生成二维码图片中带有中文显示不了的问题。

一&#xff0c;问题描述 在二维码中显示的图片中含有中文&#xff0c;不显示而是显示乱码。这是因为linux系统中为安装中文。 二&#xff0c;解决方法 1、查看所有字体&#xff1a;fc-list // 如果提示 fc-list: command not found&#xff0c;则需要安装# yum install font…

智慧排水监测系统:提高城市排水管理效率

随着城市化进程的不断推进&#xff0c;城市排水系统在城市正常运行和居民生活品质方面扮演着至关重要的角色。然而&#xff0c;随着城市化进程的加速和气候变化的加剧&#xff0c;城市排水系统面临前所未有的挑战&#xff0c;城市内涝、雨污分流不到位、河道黑臭杂乱、水体污染…

c语言练习题36:删除指定的数

删除指定的数 题目&#xff1a; 先输⼊5个整数存放在数组中&#xff0c;再输⼊⼀个整数n&#xff0c;删除数组中所有等于n的数字&#xff0c;数组中剩余的数 组保证数组的最前⾯&#xff0c;打印剩余的数字。 思路&#xff1a; 使⽤两个指针 i 和 j 。 1. i 从前往后扫描整…