首页 > 其他分享 >DAY 1: C语言异或(^)以及按位与(&)的用法

DAY 1: C语言异或(^)以及按位与(&)的用法

时间:2024-07-07 12:57:14浏览次数:24  
标签:奇数 int 结果 C语言 EOR 异或 按位 数组

1.异或(^)的定义

        在C语言中,异或操作符是^。异或操作符用于对两个操作数执行按位异或运算,即只有在两个操作数对应位不同时,结果为1。即 相同为0 不同为1。

2.重要结论

        1.任何一个数,假定为a,0^a等于a(不进位计算求和),a^a等于0。

        2.异或运算具有交换律和结合律。

3.例题(1)

        已知一个数组之中有且仅有一个数字出现的次数为奇数,求这个出现次数为奇数的数字。

        这个题正常做的话是很容易的,只需要便利整个数组,统计每个元素出现的次数,如果是奇数的就挑出来就完事了,但是时间和空间复杂度还是比较高的。所以我们可以利用异或运算的重要结论,即a^a=0,0^a=a异或具有结合律和交换律

思路:因为这个数组之中只有一个数字出现的次数是奇数次数,又如若一个数字出现偶数次,则这偶数个相同的数字异或的结果就是0,即a^a^a......^a=0。(偶数次重复,两两结合a^a=0,不会有遗留项),又如若一个数字出现奇数次a....^a=a(奇数次重复,两两结合后还会剩下一个a,即剩下0^a=a),所以整个数组经过这样的处理后就只剩下了奇数项,所以我们只需要便利整个数组,两两异或即可。

代码如下:

        

#include<stdio.h>
int main(void)
{
	int n;
	scanf("%d",&n);
	int arr[n];
	int i;
	for(i=0;i<n;i++)
		scanf("%d",&arr[i]);
	//定义一个变量,使之进行异或运算,初始化为0 最后变量的值即为奇数项
	int target=0;
	for(i=0;i<n;i++)
		target^=arr[i];
	printf("The targeting num is %d",target);
	return 0; 
 } 

4.按位与的定义

         

在C语言中,& 位运算符表示按位与操作。它会对两个操作数的每一位进行与操作,如果两个操作数的对应位都为1,则结果为1,否则为0。

例如,假设有两个8位的二进制数:10101010 和 11001100,进行按位与操作后,结果如下:

1 0 1 0 1 0 1 0

 & 

1 1 0 0 1 1 0 0=

1 0 0 0 1 0 0 0

因此,10101010 & 11001100 的结果是 10001000,即十进制中的 136。

5.例题(2) 

        已知一个数组之中有且仅有两个数字出现的次数为奇数,求这两个数字(从小到大) 

        与例题(1)不同的一点是,这个题目中出现了两个奇数,当然,我们仍然要将所有的偶数项都给去除掉,按照例题(1)的思路,仍然遍历整个数组,假定两个奇数次出现项分别为a和b,显然,此时的遍历结果就是 a^b 了,此时如果知道 a或者b 之中的任意一项,那么剩余一项也可以直接求出了,所以接下来的工作就是要求出这两项之中的其中一项。

        此时注意到,由于a!=b,所以a^b!=0,所以根据异或运算的定义,即当对应位不同时,结果为1,所以a与b的二进制形式下,二者至少有一个位是不同的,即这个位上一个为0,一个为1。

例如  二进制下的5(二进制形式为101)与4(二进制形式为100),二者唯一的差别就在与最后一位的1 和 0。

        类似地,我们可以求出任意一个两个奇数出现项所不同的位,利用这个位,可以将数组分为两大类,一类是这个位是0的(a存在),一类是这个位是1的(b存在),然后对其中的一个类进行遍历异或运算,这样去除这个类中的偶数项,就可以得到a与b其中的一个。//试着理解,确实有点拗口。

        那么我们先来找出一个二者不同的位,假定EOR=a^b=1010101001(二进制形式),对其取反,

~EOR=0101010110(取反运算符,0变1,1变0),此时再让~EOR+1,结果即为0101010111,

此时利用&的性质,只有同一位置均为1时,才为1,所以EOR&(~EOR+1)=0000000001//这个公式是用来找EOR上最右侧的1的公式。(你也可以验证正确性)所以这个公式找到了a^b的最右侧的那个1,而这个1的出现,根据异或定义,就是二者不同位的所在地之一,即一个为0 一个为1。那么这个不同的位就找到了。

        之后就可以根据这个位来对数组进行分类了,分成 0  1 两个大类 ,那么此时就可以让数组中的元素逐个与这个公式的结果进行比对,记作Judge。此时Judge为00000....1...0的形式,所以此时利用&的性质再好不过了,即同一位上都是1,结果才是1,所以如果arr[i]&Judge==0,则说明这一位一定为0,即可归类(注意:不要用arr[i]&Judge==1来判断,因为即使这一位为1,结果是可能大于1的,比如第二位都是1,则结果为2),经过遍历,则结果为a b之中的一个。

        最后,利用a^b^a==b或者a^b^b==a,即可获得另一个值,问题就解决了!!!

代码如下:

#include<stdio.h>
int main(void)
{
	int n,i;
	scanf("%d",&n);
	int arr[n];
	for(i=0;i<n;i++)
		scanf("%d",&arr[i]);
	int eor=0;
	for(i=0;i<n;i++)
		eor^=arr[i];//此时结果就是 甲^乙,若知道其中一个 就可以求异或以解
	//由于eor!=0 说明甲与乙之间一定有不同的位 0或者1
	int eor_1=0;//定义新变量 以寻找a或者b的值
	int Judge=eor&(~eor+1);//提取最右侧的1,来自甲或乙 
	for(i=0;i<n;i++)
		if((arr[i]&Judge)==0)//结果为0 则说明相应位置一定为0 
			eor_1^=arr[i];//只要满足有这个1即可,结果即为a或b,再异或即可获得b或a。
	printf("The Target Nums Are:\n");
	printf("%d %d",eor_1,eor_1^eor);
	return 0;
}

谢谢

2024/7/7

标签:奇数,int,结果,C语言,EOR,异或,按位,数组
From: https://blog.csdn.net/2301_80159044/article/details/140230879

相关文章

  • 洛谷P5726 【深基4.习9】打分——C语言
    本题思路:1.先在for循环中分别求出最大值(max),最小值(min),以及它们的和(s);2.最后将它们的和减去最大值,最小值,然后就可以求平均值了,注意是除以n-2#include<stdio.h>intmain(){  intn;  scanf("%d\n",&n);  ints=0,max=-1000,min=300000;//max要小些,min要的......
  • C语言实现字符串排序
    如果只有英文字符且不区分大小写的话按照字典序排序可以用strcmp函数,两个字符串自左向右逐个字符相比(按ASCII值大小相比较)strcmp(s1,s2)当s1<s2时,返回为负数;当s1==s2时,返回值=0;当s1>s2时,返回正数。例如"A"<"C"、"d">"D"、"computer">"compare"如果想要不区分大小写的......
  • G3.【C语言】EasyX的窗口坐标体系和绘制基本图形
    左上角是坐标原点注意标题栏不计入坐标中getwidth()获取窗口宽度getheight()获取窗口高度画点头文件COLORREFgetpixel(intx,inty); //Getpixelcolorvoidputpixel(intx,inty,COLORREFcolor); //Setpixelcolor画线头文件线的坐标voidline(intx1,......
  • 【C语言入门】初识C语言:掌握编程的基石
    ......
  • C语言教程-12_1-初识函数
    title:C语言教程-12_1-初识函数tags:[C]categories:C语言教程description:程序功能进一步复杂-使用函数进行分离提要:初步讲解C语言的函数的概念和语法前置知识:学习过数学,知道什么是数学的函数掌握C语言复合语句的概念什么是函数数学意义上的函数近代定义:......
  • C语言实战项目:贪吃蛇游戏(SnakeGame)
    前言:前面C语言的基础语法和数据结构的顺序表、链表已经学完了,我们就已经有能力去实现一个贪吃蛇项目。我们可以实现一些贪吃蛇的一些功能,例如:食物的随机生成、贪吃蛇的长度、贪吃蛇加速和减速、暂停游戏、贪吃蛇的游戏结束判定等...如下图所示:图片仅限参考真实项目视频:20......
  • 24.【C语言】getchar putchar的使用
    1.基本作用 用户输入字符,getchar()获取字符(含\n:即键入的Enter)(字符本质上是以ASCII值或EOF(-1)存储的)(与scanf有区别)putchar()打印字符(把得到的ASCII值转换成字符)(相当于printf)由于getcharputchar只操作字符,因此执行效率高例:#include<stdio.h>intmain(){intch=......
  • 使用WebSocket和C语言实现一个简单的计算器
    在现代Web开发中,WebSocket已经成为实时通信的重要工具。本文将介绍如何使用WebSocket与C语言结合,实现一个简单的计算器应用。我们将通过Go语言作为中间层,调用C语言编写的计算函数,并通过WebSocket与前端进行交互。在使用本文章代码开发过程中遇到问题,可参考博主的另外两篇博客......
  • C语言命名规范
    C语言命名规范在C语言中,命名规范对于代码的可读性和可维护性至关重要。以下是一些常见的C语言命名规律和建议变量命名变量名应该具有描述性,清晰地表达变量的用途或含义。变量名使用小写字母和下划线(snake_case)的组合,例如intmy_variable;。避免使用单个字符作为变量名,除非......
  • C语言字节对齐技术在嵌入式、网络与操作系统中的应用与优化
    第一部分:嵌入式系统中的字节对齐嵌入式系统通常对性能和资源有着严格的要求。在这些系统中,字节对齐的正确使用可以显著提高数据访问速度,减少内存占用,并提高系统的整体效率。一、嵌入式系统中的字节对齐挑战嵌入式系统中的微处理器和微控制器通常对数据访问的对齐有特定的要......