算法之位运算
前言
位运算在我们的学习中占有很重要的地位,从二进制中数的存储等都需要我们进行位运算
一、位运算复习
1.位运算复习
 按位与(&):如果两个相应的二进制位都为1,则该位的结果值才为1,否则为0
  按位或( | ):如果两个相应的二进制位中有一个为1,则该位的结果值为1,否则为0
  按位异或( ^ ):如果两个相应的二进制位值相同,则该位的结果值为0,否则为1
  按位取反( ~ ):对二进制数按位取反,即0变为1,1变为0
 
 其中我们使用最多的为异或操作, 异或操作又可以称为无进位相加。
 
2.常见的位操作
1.异或的运算规则
1. 两个相同的数异或结果为0
 2. 异或满足交换律
 3. 任何数异或0都为那个数本身
 
2.获得一个数的相反数
这个数取反加1为这个数的相反数,即( -num = (~num + 1) )
 
3.获得一个数中二进制位最右侧的1
这个数和它的相反数按位与,即( num &= -num)
 
 其他的操作我们在下面补充
二、位运算练习
1.不创建第三变量进行交换两个数的值
void Swap()
{int a = 10;int b = 20;printf("交换前:a = %d,b = %d\n", a, b);a = a ^ b;b = a ^ b;a = a ^ b;printf("交换后:a = %d,b = %d\n", a, b);
}

 此时用的是相同的数异或为0,0异或任何数都为那个数
 注意,异或操作值可以相同,但不可以对同一块空间的值进行异或,否则会变为0,比如同时对a进行异或。
 测试结果:
 
 相关练习
2.不使用比较操作返回较大的数
void Compare()
{int a = 10;int b = 20;int c = a - b;int sya = ((a >> 31) & 1);//获得a的符号位int syb = ((b >> 31) & 1);//获得b的符号位int syc = ((c >> 31) & 1);//获得c的符号位int dif = sya ^ syb;//判断a和b的符号位是否相同//符号位相同则不会产生溢出if (dif == 0){if (syc == 1){printf("最大值为:%d\n", b);}else{printf("最大值为:%d\n", a);}}//可能会产生溢出else{if (sya == 1 && syb == 0){printf("最大值为:%d\n", b);}else{printf("最大值为:%d\n", a);}}
}
测试结果:
 
注意,两个数相加或者相减都可能产生溢出的情况,下面以char为例:
 
 又比如:
 
 所以这个需要我们进行判断是否会进行溢出,这个直接返回两个数相减的结果是否大于0在溢出情况下并不适用。
 练习操作
3.不使用加减乘除等符号进行相应的操作
1.加法
//加法
int Add(int a, int b)
{int sum = a;while (b != 0){sum = a ^ b;//获得要进行进位的位置b = (a & b) << 1;a = sum;}
}

 测试结果:
 
 我们异或是不进位相加,所以下面两个数进行与是找到这两数都为1的位置,进行右移在异或相当于向前进1。
2.减法
//减法
int Sub(int a, int b)
{//获得b的相反数int sum = Add(~b, 1);//a和b的相反数进行相加sum = Add(a, sum);return sum;
}
测试结果:
 
 在这里我们可以同通过我们的add函数来得到我们的所要的相反数,原理就是我们的按位取反加1得到
3.乘法
//乘法
int Mul(int a, int b)
{int sum = 0;while (b != 0){if ((b & 1) != 0)//b当前最右侧的是否为1{sum = Add(sum, a);}//模拟相乘的过程a <<= 1;//a进行右移b >>= 1;//b进行左移}return sum;
}
测试结果:
 
 原理:二进制的乘法和十进制的乘法相同,在这里我们把十进制相乘转换为二进制相乘,我们可以通过移位来获得每个相加的数
 
4.除法
//除法
int div(int a, int b)
{int x = a < 0 ? Add(~a, 1) : a;int y = b < 0 ? Add(~b, 1) : b;int sum = 0;int i = 0;//从第31位开始进行判断for (i = 31; i > -1; i = Sub(i, 1)){if ((x >> i) >= y){sum |= (1 << i);x = Sub(x, y << i);}}return ((a < 0) ^ (b < 0)) ? Add(~sum, 1) : sum;
}
int Div(int a, int b)
{if (b == 0){//0为除数,结束程序exit(-1);}if (a == INT_MIN && b == INT_MIN){return 1;}else if (b == INT_MIN){return 0;}else if (a == INT_MIN){int sum = div(Add(a, 1), b);sum = Add(sum, div(Sub(a, Mul(sum, b)), b));return sum;}else{return div(a, b);}
}
测试结果:
 
 原理:
 
 注意:移动时要注意溢出情况,和除数是否为0。
4.整数二进制中1的个数
void Sum1()
{int a = 20;int sum = 0;while (a != 0){a &= (a - 1);sum++;}printf("1的个数为%d个\n", sum);
}

 从上面可以看出我们的( a &= (a - 1) )操作是为了消除1
 测试结果:
 
 题目练习
5.在其他数都出现两次的数组中找出现一次的一个数
void Single_num()
{int arr[] = { 1,1,2,2,3,4,4,5,5,6,6 };int sum = 0;int i = 0;for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){sum ^= arr[i];}printf("出现一次的数%d\n", sum);
}
这个就是我们使用的交换律,和两个相同的数异或结果为0
 测试结果:
 
 练习题目
6.在其他数都出现两次的数组中找出现一次的两个数
void two_Single_num()
{int arr[] = { 1,1,2,2,3,4,5,5,6,6 };int sum = 0;int i = 0;for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){//找到这两个出现一次的数sum ^= arr[i];}//获得这两数异或结果最右侧的1,这个1也是这两个数不相同的位置int sum1 = sum & (~sum + 1);int sum2 = 0;for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){//&的优先级低于 ==//把和这个不相同的一位的值进行按位与,如果结果为0;则可以分为1组if ((sum1 & arr[i]) == 0){//得到的为其中的一位sum2 ^= arr[i];}}printf("出现一次的数%d %d\n", sum^sum2,sum2);
}
测试结果:
 
 
 题目练习
7.在其他数都出现K次的数组中找出现一次的数
void k_Single_num()
{int arr[] = { 5, 4, 1, 1, 5, 1, 5 };int k = 3; int x = 0;int a[32] = { 0 };for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){//把数组中的数的每个进制位都进行相加x = arr[i];for (int j = 31; j >= 0; j--) {if (x & 1)a[j]++;x >>= 1;}}x = 0;for (int i = 0; i < 32; i++) {//对我们相加的值的每一个进制位进行相应的取模运算就是我们所要的值了x <<= 1;x += a[i] % k;}printf("%d\n", x);
}
测试结果:
 
 原理:
 
 我们可以看到在我们第i位置的值为((a[i] + b[i]) % 5),同理,在K进制中的两个数在i位上的无进位相加结果位((a[i] + b[i]) % K),所以k个相同的K进制位相加,那么相加后的结果每一位都为0。所以我们把出现的次数设置成相应的K进制位,最后把相加的结果转化为10进制就是我们所需要的值。
题目练习
总结
位运算还有许多的题目,大家可以在下面找着练习一下。
相关文章:
 
算法之位运算
前言 位运算在我们的学习中占有很重要的地位,从二进制中数的存储等都需要我们进行位运算 一、位运算复习 1.位运算复习 按位与(&):如果两个相应的二进制位都为1,则该位的结果值才为1,否则为0 按位或( | ):如果…...
 
flask使用Flask-Mail实现邮件发送
Flask-Mail可以实现邮件的发送,并且可以和 Flask 集成,让我们更方便地实现此功能。 1、安装 使用pip安装: $ pip install Flask-Mail或下载源码安装: $ git clone https://github.com/mattupstate/flask-mail.git $ cd flask-…...
 
React refers to UMD global, but the current file is a module vite初始化react项目
vite搭建react项目 初始化项目 npm create vite 在执行完上面的命令后,npm 首先会自动下载create-vite这个第三方包,然后执行这个包中的项目初始化逻辑。输入项目名称之后按下回车,此时需要选择构建的前端框架: ✔ Project na…...
 
vscode 调试 ROS2
1、在下列目录同层级找到.vscode文件夹 . ├── build ├── install ├── log └── src 2、 安装ros插件 3、创建tasks.json文件,添加下列内容 //代替命令行进行编译 {"version": "2.0.0","tasks": [{"label": &…...
 
TuyaOS开发学习笔记(2)——NB-IoT开发SDK架构、运行流程
一、SDK架构 1.1 架构框图 基于 TuyaOS 系统,可以裁剪得到的适用于 NB-IoT 协议产品接入的 SDK。SDK 将设备配网、上下行数据通信、产测授权、固件 OTA 升级等接口进行封装,并提供相关函数。 1.2 目录结构 1.2.1 TuyaOS目录说明 adapter:T…...
 
Qt应用开发(基础篇)——普通按钮类 QPushButton QCommandLinkButton
一、前言 QPushButton类继承于QAbstractButton,是一个命令按钮的小部件。 按钮基类 QAbstractButton 按钮或者命令按钮是所有图形界面框架最常见的部件,当按下按钮的时候触发命令、执行某些操作或者回答一个问题,典型的按钮有OK,A…...
Data Structures Fan(cf)
考察异或运算以及前缀和 题意大概:给你一个长度为n的a数组,一个长度为n的01字符串,会询问q次 当x的值为1 给出 l r 将 l r 区间中的0 改变为1,1改变为0 。当x的值为2是 若随后的数为0 则输出当前字符串中 是0 的a数组中的数异或 …...
 
BIOS < UEFI
Basic Input Output System (BIOS) Unified Extensible Firmware Interface (UEFI)...
 
微信最新更新隐私策略(2023-08-15)
1、manifest.json 配置修改 在mp-weixin: 参数修改(没有就添加) "__usePrivacyCheck__": true, ***2、注意 微信开发者工具调整 不然一直报错 找不到 getPrivacySetting 废话不多说 上代码 3、 编辑首页 或者用户授权界面 <uni-popup…...
Java中xml转javaBean
Java中xml转javaBean maven坐标 <dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><version>2.13.4</version></dependency>代码测试 import cn.hutool.js…...
Spring Boot集成JPA和ClickHouse数据库
简介 Spring Boot是一个用于创建独立的、基于Spring的应用程序的框架。它具有快速开发特性,可以大大减少开发人员的工作量。JPA(Java Persistence API)是Java中处理关系型数据库持久化的标准规范,而ClickHouse是一个高性能、分布…...
 
Hadoop生态圈中的Hive数据仓库技术
Hadoop生态圈中的Hive数据仓库技术 一、Hive数据仓库的基本概念二、Hive的架构组成三、Hive和数据库的区别四、Hive的安装部署五、Hive的基本使用六、Hive的元数据库的配置问题七、Hive的相关配置项八、Hive的基本使用方式1、Hive的命令行客户端的使用2、使用hiveserver2方法操…...
 
idea配置gitLab
前言:网上有很多类似的文章,但描述不够详细 步骤1:安装git 如果安装成功再次点击TEST按钮展示如下:git版本 步骤2:idea配置gitlab 查看当前项目管理的 远程仓库再git的地址,该地址可是gitLab的࿰…...
 
工程可以编译通过,但是Vscode依然有波浪线提示
前言 (1)我们在使用Vscode进行开发的时候,命名文件成功编译通过了,但是Vscode还是有波浪线的提示。 (2)其实成功编译通过就行,但是肯定还会存在一些强迫症患者,硬要消除这个报错。接…...
 
黑马JVM总结(二)
(1)栈 栈帧对应一次方法的调用,线程是要执行代码的,这些代码都是由一个个方法组成,线程运行的时候每个方法需要的内存叫做一个栈帧 (2)栈的演示 Frames:相当有栈 方法相当于栈帧…...
《Effective C++中文版,第三版》读书笔记7
条款41: 了解隐式接口和编译期多态 隐式接口:  仅仅由一组有效表达式构成,表达式自身可能看起来很复杂,但它们要求的约束条件一般而言相当直接而明确。 显式接口:  通常由函数的签名式(也就是函数名…...
 
脚本:python实现动态爱心
文章目录 效果代码Reference python实现dynamic heart 效果 代码 import turtle as tu import random as ratu.setup(0.5, 0.5) # 设置画板大小(小数表示比例,整数表示大小) tu.screensize(1.0, 1.0) # 设置屏幕大小 tu.bgcolor(black) #…...
 
【李宏毅】深度学习6:机器学习任务攻略
如果在测试集上的效果不佳,应该要做什么?Optimization 如何选择?解决 overfitting 的方法? 测试集上的效果不佳 看训练数据的loss,是不是模型本身就没训练好? 问题:model 太简单了,…...
 
如何使用SQL SERVER的OpenQuery
如何使用SQL SERVER的OpenQuery 一、OpenQuery使用说明二、 OpenQuery语法2.1 参数说明2.2注解 三、示例3.1 执行 SELECT 传递查询3.2 执行 UPDATE 传递查询3.3 执行 INSERT传递查询3.4 执行 DELETE 传递查询 一、OpenQuery使用说明 在指定的链接服务器上执行指定的传递查询。 …...
element-tree树结构-默认选中第一个节点高亮-根据id选中节点高亮
前言 tree树结构是在开发中经常使用的组件,比如区域树,楼层树,组织架构树,等等包含节点关系 实际开发可能需要我们一进到页面选中树形结构第一个节点,并且调用数据,来达到用户体验 在用户选择之后&#x…...
 
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
 
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
 
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
 
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
 
软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
