首页 > 其他分享 >位运算之异或的骚操作

位运算之异或的骚操作

时间:2023-12-20 20:59:19浏览次数:22  
标签:返回 returnA 运算 int 负数 异或 ans 操作

不用比较和判断得到两个数中的最大值

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#define u unsigned
#define ll long long
#define sc scanf
#define pr printf 
#define fr(i, j, n) for (int i = j; i < n; i++)
#define N 1001

int max(int a, int b);//返回两个数中的最大值 
int sign(int n);//返回n的符号位并翻转,也就是代表负数返回0,非负数返回1 
int flip(int n);//使n的最低位翻转 

int main(int argc, char* argv[])
{
	pr("%d", max(3, 3));
	return 0;
}
int max(int a, int b)
{
	int c = a - b;//计算a和b的差值 
	int sa = sign(a);//得到a的符号,如果a是负数返回0,不是返回1 
	int sb = sign(b);//得到b的符号,如果b是负数返回0,不是返回1 
	int sc = sign(c);//得到c的符号,如果c是负数返回0,不是返回1 
	int diff = sa ^ sb;//a和b的符号相同是1,不同为0 
	int same = flip(diff);//两种状态互斥,所以直接翻转就行了。 
	int returnA = same * sc + diff * sa;//如果a和b符号相同并且c是个非负数代表a是最大的,或者a和b符号不相同并且a是个非负数,那么返回a
	//因为diff和same互斥,所以只会中一边相当于if,这里还是很妙的 
	int returnB = flip(returnA);
	//只可能返回一个数所以returnA和returnB也互斥,直接翻转就可以了。 

	return returnA * a + returnB * b;//returnA是1代表返回a,returnA是0代表返回b,returnA和returnB互斥,所以只会有一个是0,另一个是1 
}
int sign(int n)
{
	return flip((n >> 31) & 1);//负数返回0,非负数返回1 
}
int flip(int n)//n只能使0或者1 
{
	return n ^ 1; 
}

一个数组中有两个数出现了奇数次,其他数出现了偶数次,求出这出现奇数次的两个数

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* singleNumber(int* nums, int numsSize, int* returnSize) {
    int ans = 0;//把所有数异或起来,最后ans的值是两个奇数的异或的结果

    for (int i = 0; i < numsSize; i++) {
        ans ^= nums[i];
    }

    //防止溢出,因为INT_MIN无法的到它的绝对值
    int r = ans == INT_MIN? ans: ans & (1 * -ans);//取出ans的最右边的1
    int res = 0;//去异或在二进制中有ans最右边的1的数,最后res一定是两个数中的一个

    for (int i = 0; i < numsSize; i++) {
        if (nums[i] & r) {
            res ^= nums[i];
        }
    }

    int* p = (int*)malloc(sizeof(int) * 2);
    *returnSize = 2;
    p[0] = ans ^ res;//根据异或的性质来求出另一个数
    p[1] = p[0] ^ ans;//根据异或的性质来求出另一个数

    return p;
}

异或运算符是满足结合律和交换律的,然后相同的数异或的结果是0,一个数和零异或还是它本身。

标签:返回,returnA,运算,int,负数,异或,ans,操作
From: https://www.cnblogs.com/lwj1239/p/17917536.html

相关文章

  • C 语言运算符详解
    C语言中的运算符运算符用于对变量和值进行操作。在下面的示例中,我们使用+运算符将两个值相加:intmyNum=100+50;虽然+运算符通常用于将两个值相加,就像上面的示例一样,它还可以用于将变量和值相加,或者将变量和另一个变量相加:intsum1=100+50;//150(100+5......
  • C 语言运算符详解
    C语言中的运算符运算符用于对变量和值进行操作。在下面的示例中,我们使用+运算符将两个值相加:intmyNum=100+50;虽然+运算符通常用于将两个值相加,就像上面的示例一样,它还可以用于将变量和值相加,或者将变量和另一个变量相加:intsum1=100+50;//150(100+......
  • EasyCVR平台如何通过api接口设置实时流的sei数据实现画框等操作?
    为了便于用户自由调用、集成与二次开发,EasyCVR平台也提供了丰富的API接口供大家使用。今天我们来分享一下如何通过API接口设置实时流的SEI数据,实现在视频播放器中展示文本内容、画框等操作?1)后端接口调用如下:接口URL:POSThttp://127.0.0.1:18000/api/v1/sei/set2)接口参数如下:3)调用成......
  • debezium同步Oracle数据时,更新操作只有被变更字段,其余字段值为null,主键ID值为0
    1.情景展示使用debezium的Oracle插件(io.debezium.connector.oracle.OracleConnector)自动读取Oracle的归档日志。当我对Oracle数据库受监控的表(待同步表),进行更新操作后,debezium会自动将变更记录推送到kafka当中。新增和删除操作,数据都能同步到另一个数据库。但是,更新操作,数据......
  • 安防监控EasyCVR平台如何通过api接口设置实时流的sei数据实现画框等操作?
    国标GB28181视频监控系统EasyCVR平台采用了开放式的网络结构,支持高清视频的接入和传输、分发,能提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力,此外,高清可视化视频监控平台EasyCVR还具......
  • ● Zabbix——操作系统加入
    zabbix-get用户测试server端是否可以连通agent的key,并取回值。安装:yuminstallzabbix-get如果不知道路径,可以通过下方命令查找。find/-namezabbix_get安装完成后,可以下面命令来测试是否可以连通agent-s--host:指定客户端主机名或者IP-p--port:客户端端口,默认10050-I......
  • Java学习之apache poi操作Excel文件
    创建Java项目,然后加入Maven依赖如下:读取指定的Excel文件写入既存的Excel文件 创建新的Excel,添加文件内容......
  • pyinstaller 打包 win32ctypes.pywin32.pywintypes.error: (225, '', '无法成功完成操
    背景:使用python写了一个程序,使用pyinstaller打包,不使用-w--noconsole的命令打包隐藏命令行窗口时,是正常的,但是使用-w或者--noconsole就会报错win32ctypes.pywin32.pywintypes.error:(225,'','无法成功完成操作,因为文件包含病毒或潜在的垃圾软件。')在网上搜索了一些资讯,......
  • java 特殊操作流
    一、输入流和输出流  1、输入流 2、输出流 二、字节打印流和字符打印流 1、字节打印流 2、字符打印流 三、对象序列化流和对象反序列化流1、对象序列化流 ......
  • 【SpringBootWeb入门-15】Mybatis-基础操作-增改查操作
    1、章节回顾上一篇文章我们讲解了Mybatis的删除操作,本篇继续学习Mybatis的新增操作:根据员工表字段,新增员工表的数据,新增的字段有:用户名、员工姓名、性别、图像、职位、入职日期、归属部门。2、增删改查操作-新增操作员工表emp新增数据,对应的SQL语句:insertintoemp(username......