算法之位运算

news2024/12/23 20:35:17

前言

位运算在我们的学习中占有很重要的地位,从二进制中数的存储等都需要我们进行位运算

一、位运算复习

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进制就是我们所需要的值。

题目练习

总结

位运算还有许多的题目,大家可以在下面找着练习一下。

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

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

相关文章

Spring Batch:处理大数据和批量任务的解决方案

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

聚类分析 | MATLAB实现基于SOM自组织特征映射聚类可视化

聚类分析 | MATLAB实现基于SOM自组织特征映射聚类可视化 目录 聚类分析 | MATLAB实现基于SOM自组织特征映射聚类可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于自组织特征映射聚类算法(SOM)的数据聚类可视化 可直接运行 注释清晰 Matlab语言 1.多特征输入&…

数据接口工程对接BI可视化大屏(四)创建工程

第4章 创建工程 4.1 新建工程 在IDEA中新建工程&#xff0c;并使用SpringInitializr来创建&#xff1a; 点击下一步&#xff0c;输入项目的GAV坐标及工程构造方式后点击下一步&#xff1a; 点击下一步&#xff0c;选择主版本和模块&#xff0c;这里以Spring2.x版本为例&#…

Spring Reactive:响应式编程与WebFlux的深度探索

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

CLEAN-SC波束形成声源识别改进

CLEAN-SC 波束形成声源识别方法计算速度快、成像干净清晰、结果准确度高&#xff0c;但当传统延迟求和算法在各声源处输出的主瓣严重融合时&#xff0c;亦无法准确分辨声源。造成该缺陷的原因为: 主瓣严重融合时&#xff0c;CLEAN-SC 所基于的延迟求和输出峰值所在聚焦点即为声…

一、认识GitHub项目 —— TinyWebServer

认识GitHub项目 —— TinyWebServer 一、前言 这个项目是Linux下C轻量级Web服务器。几乎是想从事C服务器开发方向的同学的必备初始项目了。属于那种&#xff0c;“烂大街”&#xff0c;但是你又不能不会的项目。 对这个项目笔者打算多分几章讲解&#xff0c;帮助刚用GitHub&a…

系统架构设计高级技能 · 通信系统架构设计理论与实践

现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in reality. 点击进入系列文章目录 系统架构设计高级技能 通信系统架构设计理论与实践 一、通信系统网络架构1.1 局域…

音视频质检及画质评估——为QoS QoE 指标保驾护航

// 腾讯已有超过21年的音视频技术积累&#xff0c;独家具备 RT-ONE 全球网络。此外&#xff0c;构建了包括实时音视频、云直播、云点播、即时通信、媒体处理等业界最完整的 PaaS 及 aPaaS 产品家族&#xff0c;面向各大场景提供低代码解决方案&#xff0c;开发者和企业可以快…

lighttpd以及socket和WebSocket编程

综述 本文涉及到下图绿色背景部分的内容&#xff1a; 左侧位于Linux下&#xff0c;其中包括lighttpd和socket程序&#xff1b;右侧是WebSocket程序。两者通过网络交互。 本文介绍lighttpd的基本使用方式&#xff0c;并通过编程完成一个socket服务器与浏览器端的WebSocket客户…

180B参数的Falcon登顶Hugging Face,vs chatGPT 最好开源大模型使用体验

文章目录 使用地址使用体验test1:简单喜好类问题test2:知识性问题test3:开放性问题test4:中文支持test5:问题时效性test6:学术问题使用地址 https://huggingface.co/spaces/tiiuae/falcon-180b-demo 使用体验 相比Falcon-7b,Falcon-180b拥有1800亿的参数量

【数据结构】AVL树的插入和自平衡调整

AVL树是最早发明的自平衡二叉查找树。在AVL树中&#xff0c;任一节点对应的两颗子树的最大高度差为1&#xff0c;因此他被称为高度平衡树。查找、插入和删除在平均和最坏情况下的时间复杂度都是 O ( log ⁡ n ) O(\log{n}) O(logn)增加和删除操作后可能需要通过一次货多次旋转…

斯坦福兔子,犰狳,obj模型下载

序 这俩&#xff0c;可能是计算机图形学里比较有名的模型。 但是&#xff0c;官方网站上下载的话&#xff0c;模型是ply格式的&#xff0c;不大习惯&#xff1b;想要obj格式的。 有没有现成的obj格式的&#xff1f; 相关网页 PositionBasedDynamics/data/models at master…

动态规划之子数组系列

子数组系列 1. 环形⼦数组的最⼤和2. 乘积最大子数组3. 等差数列划分4. 最长湍流子数组5. 单词拆分6. 环绕字符串中唯⼀的子字符串 1. 环形⼦数组的最⼤和 1.题目链接&#xff1a;环形⼦数组的最⼤和 2.题目描述&#xff1a;给定一个长度为 n 的环形整数数组 nums &#xff0c…

Pytorch-基于RNN的不同语种人名生成模型

一、RNN背景介绍 循环神经网络&#xff08;Recurrent Neural Networks, RNN&#xff09; 是一种常用的神经网络结构&#xff0c;它源自于1982年由Saratha Sathasivam提出的霍普菲尔德网络。 其特有的循环概念及其最重要的结构——长短时记忆网络——使得它在处理和预测序列数据…

Linux初探 - 概念上的理解和常见指令的使用

目录 Linux背景 Linux发展史 GNU 应用场景 发行版本 从概念上认识Linux 操作系统的概念 用户的概念 路径与目录 Linux下的文件 时间戳的概念 常规权限 特殊权限 Shell的概念 常用指令 ls tree stat clear pwd echo cd touch mkdir rmdir rm cp mv …

请求与响应以及REST风格

目录 请求与响应请求参数参数传递 五种类型参数传递普通参数POJO数据类型嵌套POJO类型参数数组类型参数集合类型参数JSON数据传输参数JSON对象数据JSON对象数组 响应返回文本数据[了解]响应JSON数据 REST风格REST简介RESTful入门案例RESTful快速开发 请求与响应 请求参数 参数…

【SpringMVC】实现增删改查(附源码)

目录 引言 一、前期准备 1.1.搭建Maven环境 1.2.导入pom.xml依赖 1.3.导入配置文件 ①jdbc.properties ②generatorConfig.xml ③log4j2.xml ④spring-mybatis.xml ⑤spring-context.xml ⑥spring-mvc.xml ⑦修改web.xml文件 二、逆向生成增删改查 2.1.导入相关u…

网络原理,了解xml, json,protobuffer的特点

目录 外卖服务器场景带入 大佬们通用的规范格式 一、&#x1f466; 外卖服务器场景 外面服务器沟通有很多模式——展示商家列表等等&#xff0c;只是其中一个&#xff0c;因此需要一个统一的规划了——不同应用程序&#xff0c;里面的自定义格式是不一样的&#xff0c;这样的…

基于微服务+Java+Spring Cloud +UniApp +MySql开发的智慧工地源码(物联网、人工智能、AI识别、危大工程)

智慧工地系统利用物联网、人工智能、云计算、大数据、移动互联网等新一代信息技术&#xff0c;通过工地中台、三维建模服务、视频AI分析服务等技术支撑&#xff0c;实现智慧工地高精度动态仿真&#xff0c;趋势分析、预测、模拟&#xff0c;建设智能化、标准化的智慧工地综合业…

LeetCode 49题: 字母异位词分组

题目 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "nat&qu…