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

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

目录

  • 位操作符:
  • 一些题目:
    • 不创建临时变量交换整数
    • 整数转换
    • 二进制中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

总结:

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin判断null比较let布尔值Boolean

Kotlin判断null比较let布尔值Boolean class MyData {val count: Int? 2023val number: Int? null }fun main(args: Array<String>) {val data MyData()val year 2022if (data.count ! null) {if (data.count > year) {println("data.count ! null")}}…

Linux内核数据结构 散列表

1、散列表数据结构 在Linux内核中&#xff0c;散列表&#xff08;哈希表&#xff09;使用非常广泛。本文将对其数据结构和核心函数进行分析。和散列表相关的数据结构有两个&#xff1a;hlist_head 和 hlist_node //hash桶的头结点 struct hlist_head {struct hlist_node *first…

App卡帧与BlockCanary

作者&#xff1a;图个喜庆 一&#xff0c;前言 app卡帧一直是性能优化的一个重要方面&#xff0c;虽然现在手机硬件性能越来越高&#xff0c;明显的卡帧现象越来越少&#xff0c;但是了解卡帧相关的知识还是非常有必要的。 本文分两部分从app卡帧的原理出发&#xff0c;讨论屏…

ElasticSearch总结

ES是什么 ES是一个天生支持分布式的搜索、聚合分析的存储引擎 基于Java开发 基于Lucene的开源分布式搜索引擎 ELK &#xff1a; elasticSearch Logstah Kibana 加入 Beats 后 ELK 改为 &#xff1a;Elastic stack ES解决了什么问题 ES解决的核心问题 &#xff1a; 1.海量数…

pinia——添加插件——基础积累

问题&#xff1a;是否给pinia添加过插件&#xff1f;具体添加的方式是什么&#xff1f; 在pinia中&#xff0c;我们可以为仓库添加插件&#xff0c;通过添加插件能够扩展以下的内容&#xff1a; 为 store 添加新的属性 定义 store 时增加新的选项 为 store 增加新的方法 包装现…

three.js(六):自适应设备分辨率

自适应设备分辨率 当今大多数的PC端和移动端显示器都是HD-DPI显示器。HD-DPI 是High Definition-Dots Per Inch 的简称&#xff0c;意思是高分辨率显示器。不同设备的显示器的分辨率是不一样的。 以上图中的iPhone6/7/8 为例&#xff1a;375*667 代表的手机的屏幕的物理尺寸&a…

本地套接字通信

1.本地套接字 本地套接字的作用&#xff1a;本地的进程间通信 有关系的进程间的通信 没有关系的进程间的通信 本地套接字实现流程和网络套接字类似&#xff0c;一般采用TCP的通信流程 2.本地套接字通信的流程 - tcp // 服务器端 1.创建监听的套接字int lfd socket(AF_U…

顺序表链表OJ题(3)——【数据结构】

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 前言&#xff1a; 今天是链表顺序表OJ练习题最后一次分享&#xff0c;每一次的分享题目的难度也再有所提高&#xff0c;但是我相信大家都是非常机智的&#xff0c;希望看到博主文章能学到东西的可以一键三连关注一下博主…

数据库——Redis 单线程模型详解

文章目录 Redis 基于 Reactor 模式来设计开发了自己的一套高效的事件处理模型 &#xff08;Netty 的线程模型也基于 Reactor 模式&#xff0c;Reactor 模式不愧是高性能 IO 的基石&#xff09;&#xff0c;这套事件处理模型对应的是 Redis 中的文件事件处理器&#xff08;file …

科技政策 | 四川省科学技术厅关于发布2024年第一批省级科技计划项目申报指南的通知

原创 | 文 BFT机器人 近日&#xff0c;四川省科学技术厅发布了2024年第一批省级科技计划项目申报指南&#xff1b;其中包括自然科学基金项目、重点研发计划、科技成果转移转化引导计划、科技创新基地&#xff08;平台&#xff09;和人才计划。 01 自然科学基金项目 实施周期 …

聚类分析 | MATLAB实现基于DBSCAD密度聚类算法可视化

聚类分析 | MATLAB实现基于LP拉普拉斯映射的聚类可视化 目录 聚类分析 | MATLAB实现基于LP拉普拉斯映射的聚类可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于DBSCAD密度聚类算法可视化&#xff0c;MATLAB程序。 使用带有KD树加速的dbscan_with_kdtree函数进行…

你的住宅安全吗?这个技能赶紧学学

随着城市化的不断加速和人口增长&#xff0c;住宅小区的管理和安全问题也愈发凸显出来。在这种背景下&#xff0c;门禁监控系统成为了一种既有效又实用的解决方案。 门禁监控系统不仅可以控制和管理出入小区的人员和车辆&#xff0c;还可以提供实时监控和记录&#xff0c;为小区…

C++ Day6

目录 一、菱形继承 1.1 概念 1.2 格式 二、虚继承 2.1 作用 2.2 格式 2.3注意 三、多态 3.1函数重写 3.2 虚函数 3.3 赋值兼容规则 3.4 多态中&#xff0c;函数重写的原理 3.5 虚析构函数 3.5.1 格式 3.6 纯虚函数 3.6.1格式 四、抽象类 五、模板 5.1模板的特…

CTFhub-sqli注入-报错注入

用到的函数 updatexml(1&#xff0c; &#xff0c;1) concat(0x7e, ,0x7e) group_concat(目标值) right(&#xff0c;32) 1 1 1 union select updatexml(1,concat(0x7e,database(),0x7e),1) 1 union select updatexml(1,concat(0x7e,(select(group_concat(ta…

Vue3 学习

基础 js:https://www.bilibili.com/video/BV15T411j7pJ/?spm_id_from333.337.search-card.all.click&vd_source9747207be61edfe4ec62226fc79b3589 官方文档&#xff1a; https://cn.vuejs.org/ 版本之间差异在关于---》版本发布 https://cn.vuejs.org/about/release…

Matter 设备配网流程 ---- 配网材料和 SPAKE2P 机制

Matter 设备配网流程 ---- 配网材料和 SPAKE2P 机制 1. Matter 配网材料 Matter 配网&#xff08;commissioning&#xff09;使用 SPAKE2P 协议完成 PASE&#xff0c;进而验证 DAC&#xff08;Device Attestation Credentials&#xff09;&#xff0c;派发 NOC&#xff0c;然…

MySQL的日志undolog、binlog、redolog

1. 日志层次 binlog是Server层&#xff0c;undolog和redolog是innodb引擎层特有的。 2. 记录了什么 & 作用 binlog 记录了所有数据库结构变更和表数据修改的SQL日志。 主要用于数据备份和主从复制&#xff0c;比如误删数据了可以用binlog找回。 undolog 如下图&#…

计算机网络-笔记-第五章-运输层

目录 五、第五章——运输层 1、运输层概述 2、运输层端口号、复用、分用 &#xff08;1&#xff09;熟知端口号、登记端口号、短暂端口号 &#xff08;2&#xff09;熟知端口号 &#xff08;3&#xff09;发送方复用、接收方分用 3、UDP与TCP对比 &#xff08;1&#x…

什么是响应式图片?如何在网页中实现响应式图片?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 响应式图片&#xff08;Responsive Images&#xff09;⭐ 实现响应式图片的方法1. 使用<img>标签的srcset属性2. 使用<picture>元素3. 使用CSS的max-width属性4. 使用响应式图片库 ⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&…

【AI】数学基础——高数(函数微分部分)

参考&#xff1a;https://www.bilibili.com/video/BV1mM411r7ko?p1&vd_source260d5bbbf395fd4a9b3e978c7abde437 唐宇迪&#xff1a;机器学习数学基础 文章目录 1.1 函数1.1.1 函数分类1.1.2 常见函数指/对数函数分段函数原函数&反函数sigmod函数Relu函数(非负函数)复…