常见的位操作及其应用

C语言之位操作 假设要清零变量的第n位到第m位(n 阅读详情

概述

与、或、异或、取反或者移位运算这几种基本的位操作想必诸位读者并不陌生,如果我们能在某些合适场景下使用位运算,有些时候可以大大提高算法的效率。但由于本身位运算太过灵活,甚至某些技巧比较苦涩难懂,因而,本篇文章主要介绍几种常见的或者有趣的位操作,并且给出一些用到这些技巧的算法题目,便于读者练习。

有趣的操作

1. 大小写字母转换

  1. 利用或操作和空格将英文字母转成小写
('a' | ' ') = 'a';
('A' | ' ') = 'a';
  1. 利用与运算&和下划线将英文字符转换成大写
('b' & '_') = 'B';
('B' & '_') = 'B';
  1. 利用异或运算^和空格进行英文字符大小写互换
('d' ^ ' ') = 'D';
('D' ^ ' ') = 'd'

常用指数: 🔯🔯

容易指数:🔯🔯🔯

PS:上述技巧能够产生奇特效果的原因在于字符类型的数据都是通过ASCII进行编码的,字符本身其实就是数字,而刚好这些字符对应的数字通过位运算符就可以得到正确结果,此处就不展开来说了。

2. 判断两个数是否异号

int x = -1, y = 2;
boolean f = ((x ^ y) < 0); // true 两个int类型数据进行异或运算小于零证明异号

int x = 1, y = 2;
boolean f = ((x ^ y) < 0); // false 两个int类型数据进行疑惑运算大于零证明同好

常用指数:🔯🔯🔯

困难指数:🔯

PS:这个操作在我们判断两个数异号的时候非常有用,一方面运算效率较高,另一方面可以减少if else 分支的使用。其背后的原理主要是一个正数补码的符号位和一个负数补码的符号位肯定想法,经过疑惑运算后,最后符号位结果肯定是1(代表负数)。

3. 移除最后一位"1"

byte n = 10;
// n的二进制表示为: 0 0 0 0 1 0 1 0
//       异或运算  ^
//n-1的二进制表示为:0 0 0 0 1 0 0 1
n & (n-1); //结果为:0 0 0 0 1 0 0 0

image-20201027142445416

根据上边的注释以及示意图,整个操作过程应该不难理解

简单来说n & (n -1 )主要作用:就是消除数字n的二进制表示中的最后一个1.

常用指数:🔯🔯🔯🔯🔯

困难指数:🔯🔯

PS:这个操作特别常用,在好多leetcode题目中都有涉及,比如用来判断一个数的二进制数中1的个数。

4. 获取最后一个1

byte n = 10;
//结果为:0 0 0 0 0 0 1 0
(n & (n-1)) ^ n;

常用指数:🔯🔯🔯🔯

困难指数:🔯🔯🔯

PS:该操作刚好和[操作3](# 3. 移除最后一位"1")相反,主要是为了获取数字n的二进制表示中的最后一个1.该操作通常会用在位标记的时候使用(可参考[汉明距离](#2. 汉明距离))。

5. 异或运算的简单性质

a=0^a=a^0

0=a^a

常用指数:🔯🔯🔯🔯

困难指数:🔯

PS:这个性质在我们判断两个数是否相同的时候非常常用。

应用

前边总结了那么多常用的位操作,下边来做几道题消化吸收一下刚刚所学的知识。

1. 只出现一次的数字

image-20201027144825355

这道题比较简单,说实话即使不用位运算我们也可以有好多种方法求解,比如可以用一个Map来对元素进行boolean标记来求解。但如果我们此处能想到用异或运算的性质,那这道题目我们便可以简单优雅的解出来。

思路:用一个初值为0的变量不断和数组中的元素进行异或运算,最终得到的变量值便是最终结果。

原因:因为0和任何一个元素进行异或运算都是0,而任何两个相同元素进行异或之后的结果都是0,而题目中只有一个数是单独存在的,其他数都是2个,因而不断进行异或运算最后的结果必然是那个独特的数值,也就是最终的结果。

代码如下:

public int singleNumber(int[] nums) {
        int result = 0;
        for (int i =0;i<nums.length;i++){
            result ^=nums[i];
        }
        return result;
    }

2. 汉明距离

image-20201027151241300

这个问题,我们常规思路可能是通过一次for循环并且在循环过程中判断不同位置的二进制位是否相同,同时做计数。

但同样的我们通过位运算可以比较快速的解决该问题

思路:通过一次异或运算,获取一个不同位置二进制数构成的一个整数,然后计算该整数中1的个数即为最终结果。在计算1个数的时候一个小技巧,可以通过n & (n-1)不断做移位运算来计算。

实现代码如下:

public int hammingDistance(int x, int y) {
    x = x ^ y;
    int count = 0;
    while (x != 0) {
      x = x & (x - 1);
      count++;
    }
    return count;
  }

1. 只出现一次的数字 III

image-20201027202928617

这个问题跟[只出现一次的数字](#1. 只出现一次的数字)很像,主要差别可能在这个唯一的数是两个,而不是一个。同样的这个问题有很多常规的结果,比如街主要map来统计和标注每个数字出现的次数。但我们使用位运算的时候我们会发现其速度是极快的。

思路:

前面分析了此题目和原来题目的最大区别在于只出现一次的数字不再是唯一的了,而变成了两个。因而我们考虑能否对着集合元素按照某种标准做一个分类,经过分类之后,每一个类别都分别包含一个特殊的元素以及若干相同的元素。此时该问题就转换成了[问题1](#1. 只出现一次的数字),那个简单的问题。

其实分类标准应该不难找,由于这两个元素是不相等的,因此这两个元素的某个二进制位必然是不相等。因此我们可能考虑根据该二进制位为0或者1将数组分成A组合B组。而这个数组中其它数字要么就属于A组,要么就属于B组。再对A组和B组分别执行“异或”解法就可以得到A,B了。而要判断A,B在哪一位上不相同,只要根据A异或B的结果就可以知道了,这个结果在二进制上为1的位就说明A,B在这一位上是不相同的。

比如:

int a[] = {1, 1, 3, 5, 2, 2}

整个数组异或的结果为3^5,即 0x0011 ^ 0x0101 = 0x0110

对0x0110,第1位(由低向高,从0开始)就是1。因此整个数组根据第1位是0还是1分成两组。

a[0] =1  0x0001  第一组

a[1] =1  0x0001  第一组

a[2] =3  0x0011  第二组

a[3] =5  0x0101  第一组

a[4] =2  0x0010  第二组

a[5] =2  0x0010  第二组

第一组有{1,1,5},第二组有{3,2,2},然后对这二组分别执行“异或”解法就可以得到5和3了。\

实现代码如下:

public int[] singleNumber(int[] nums) {
    int xorVal = 0;
    for (int num : nums) {
        xorVal ^= num;
    }
    // 获取最后一个 1
    xorVal = (xorVal & (xorVal - 1)) ^ xorVal;

    int res[] = new int[2];
    //根据和xorVal的与运算结果不同进行分类
    for (int num : nums) {
        if ((num & xorVal) == 0) {
            res[0] ^= num;
        } else {
            res[1] ^= num;
        }
    }
    return res;
}

总结

以上便是一些常用的位操作,以及对应的一些简单应用。其实关于微操作的技巧很多,有很多也非常有趣,其中有一个叫做 BitTwiddling Hacks 的外国网站收集了几乎所有位操作的黑科技玩法,感兴趣的话,可以看一看哈!!

参考

  1. https://leetcode-cn.com/problems/single-number-iii/solution/java-yi-huo-100-yao-shi-kan-bu-dong-wo-jiu-qu-chu-/
  2. https://greyireland.gitbook.io/algorithm-pattern/shu-ju-jie-gou-pian/binary_op#chang-jian-ti-mu
AHB不对称半桥反激电路设计(一)变换器拓扑工作原理详解 本文详细分析了AHB(不对称半桥)反激变换器拓扑的工作原理及关键优势。该拓扑通过谐振腔结构实现原边功率管的零电压开通(ZVS)和副边整流管的零电流关断(ZCS),显著提升效率至95%以上。文章阐述了6个工作阶段的时序特征,包括谐振电感电流和电容电压的数学模型推导。AHB拓扑具有漏感能量回收、宽电压输出(适配PD快充等场景)和协同储能等优势,相比传统方案可缩小变压器体积30%,成为100-300W隔离电源的理想选择。 阅读详情

相关推荐

海康VisionMaster表面缺陷滤波实战:从参数调优到工业检测避坑指南

本文深入探讨海康VisionMaster表面缺陷滤波技术在工业检测中的应用,从参数调优到ROI绘制与Blob分析的协同策略,提供金属外壳、锂电池铝壳等复杂表面的缺陷检测实战指南。通过多级滤波架构和动态ROI生成法,显著提升检出率至98.7%,误检率低于0.5%,为工业质检提供智能化解决方案。

ujm5678901的博客 326

位运算实际运用

前言:1.位运算1.1 & 按位与1.2 << 左位移2.二进制运算业务逻辑分析 前言: 日常开发中位运算不是很常用,但是巧妙的使用位运算可以大量减少运行开销,优化算法。 今天在翻看公司业务代码时发现一个功能模块中有运用到很多的二进制位运算来进行业务操作,心中不禁惊叹,牛人啊!后来经过领导的指点,自己也开始了解其中逻辑,特写下此文,记录并分享。 1.位运算 &:按位与。 |:按位或。 ~:按位非。 ^:按位异或。 <<:左位移运算符。 >>:右位移运算.

Marikty的博客 964

RV1106G3的fastboot调试

本文详细描述了在幸狐的Luckfox Pico Ultra硬件平台上,使用官方SDK进行系统优化和YOLOv5s模型部署的过程。首先,硬件板卡使用幸狐的SDK进行EMMC非Fastboot配置时功能正常,但Fastboot配置编译失败,通过修改设备树中的ramdisk大小解决了编译问题,但运行时仍报错。幸狐提供的Fastboot烧录文件可正常运行,表明硬件支持Fastboot。随后,使用官方SDK版本rv1106_rv1103_240813进行编译和调试,发现EMMC Fastboot启动失败,通过修改U-

fzktongyong的博客 2354

<<算法很美>>——(一)常用位操作

目录 1. 位运算与进制基础 2. 几个有趣的位操作 3. 运用n&(n-1) 一题三解:二进制中1的个数 判断一个数是不是2的指数 牛刀小试 4. 运用a^a=0 找出落单的数 牛刀小试 5. 位运算思维提升 将整数的奇偶位互换 二进制表示浮点实数​ 出现K次与出现一次 1. 位运算与进制基础 位运算的奇淫技巧: 判断奇偶数 获取二进制位是1或0 交换两个整数变量的值 不用判断语句,求整数的绝对值 >>和<<运算符将二进制位进行

m0_58367586的博客 1387

反激开关电源变压器设计实战:从理论到绕制的完整流程解析

本文详细解析了反激开关电源变压器的完整设计流程,从核心理论到实战绕制。文章以24W电源为例,手把手讲解如何根据输入输出电压、功率和频率等关键参数,计算匝比、峰值电流、电感量,并完成磁芯选择、匝数确定、气隙计算及线径选取。重点阐述了CCM模式下的设计要点与绕制工艺,旨在帮助工程师设计出稳定高效的反激变压器,避免常见陷阱。

weixin_29305313的博客 683

Linux8.3上装Oracle 19c RAC,ssh互信总报INS-06006?别急着下补丁,试试这个临时替换scp的骚操作

本文针对在Linux 8.3上安装Oracle 19c RAC时遇到的SSH互信报错INS-06006问题,提供了一个无需官方补丁的临时解决方案。通过创建SCP包装脚本并添加-T参数,有效解决了OpenSSH 8.x版本与Oracle安装程序的兼容性问题,帮助用户顺利完成安装流程。

weixin_30764883的博客 402

常用的位操作

常用的位操作

qq_43230771的博客 699

麒麟系统下的多媒体革命:VLC在kylinV10上的性能优化与调试技巧

本文详细介绍了在麒麟kylinV10系统上优化VLC多媒体播放性能的实战技巧,特别针对飞腾FT-2000/4硬件平台。从源码编译调优到硬件加速配置,提供全面的性能提升方案,帮助开发者在国产操作系统上构建高效媒体播放环境。

weixin_29168675的博客 457

C++中 的位操作及其部分经典运用

1.位操作的介绍 位操作有: 与:& 或:| 取反:~ 取反符号与非!的区别: !是逻辑运算符(与||,&&是一类符号),表示逻辑取反,可以把非0值变成0,把0值变为1 ~是位运算符(与|,&是一类符号),表示按位取反,在数值的二进制表示上,将0变为1,将1变为0 异或:^ 位移操作:(左移:<< , 右移:>>) 位操作只能用于整形数据,对float和double类型进行位操作会被编译器报错 需要注意的是由于编...

weixin_42067304的博客 1304

生信人填坑记 orthofinder的安装和基础使用

其中常用的有两个结果,第一个是Orthogroups文件夹下的Orthogroups.GeneCount.tsv,这个文件里保存着每个家族在每个物种里的成员数量。(写到这儿饭点到了,吃饭要紧…在国内使用conda的同学我相信很多人都会遇到-|- -|- -|- -|- -|- -|- -|- -|- 一直转圈。软件的是由很简单,将你要跑的物种的蛋白质文件放在work/data目录下,文件名都用物种缩写,后缀统一就行。当然,很多软件都会自带一个这样的文件,conda装不了的时候可以去软件官网溜达溜达。

qq_43337286的博客 5381

Intel Realsense windows安装与入门

realsense400系列介绍: https://www.intelrealsense.com/stereo-depth/?utm_source=intelcom_website&utm_medium=button&utm_campaign=day-to-day&utm_content=D400_learn-more_button realsense 435i介绍: ...

hanshuning的专栏 1万+

论位操作的重要性

原文网址: http://forwell.me/2016/03/27/Importance-of-Bit-Operation/ 随着Leetcode刷题计划的推进,发现位操作越发的重要,很多时候甚至是离开了位操作运算,你压根就没法解决这个问题。熟练使用位操作会让你有事半功倍的效果,那下面我们就来看看位操作是如何事半功倍的。 为什么要学习位操作运算 从一些小的列子说起 1.交换两个变

diaozaoxiang的博客 716

光电二极管探测器电流信号处理与指令输出系统

本文提出了一种基于Python的光电二极管电流信号处理系统设计方案。该系统能够实时采集、处理光电二极管输出的电流信号,并根据预设阈值输出控制指令。系统采用模块化架构,包含数据采集、信号处理、阈值检测、指令生成等核心模块。其中数据采集模块提供了模拟器实现和硬件接口框架,支持噪声模拟和脉冲信号生成。系统设计考虑了实时性、可靠性和可扩展性,适用于光强测量、光电检测等多种应用场景。

huanghm88的专栏 1180

位操作一般怎么用?

位操作一般怎么用? 转载于:https://www.cnblogs.com/lulinan/p/3173885.html

weixin_34310785的博客 96

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

简述位操作符

简述位操作符额,似乎这不应该由我来写,不过既然已经开始写了,那就把它完成好了~  大家都知道,数据在计算机中是以二进制的方式进行储存,而二进制只用0和1来表示数,如果对应成真值,则是True或False 。0和1往往给人一种简谐美的感觉,正如莱布尼茨所说,他从0和1中看到了宇宙的创生。额,似乎跑题了,拉回来~  而位操作符则是用来通过对存储的二进制数操作的一些符号。  PS:如非特殊声明,以下

fly_902的专栏 749

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

位操作算法基本操作1

常见的位操作 位操作 符号 运算规则 与 & 两个位都为1时,结果才为1 或 | 两个为都为0时,结果才为0 异或 ^ 两个位为0,1时,结果才为1 取反 ~ 0变1,1变0 左移 << 二进位全部左移,高位丢弃,低位补零 右移 >> 二进位全部右移,无符号数,高位补零 细节1.位操作只能用于整数数据,对float,d

独行的博客 768

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

[转载]位操作

以下内容来自http://blog.youkuaiyun.com/morewindows/article/details/7354571 符号 描述 运算规则 by MoreWindows & 与 两个位都为1时,结果才为1 |...

badu1904的博客 148

位操作总结

Wiki Bit manipulation is the act of algorithmically manipulating bits or other pieces of data shorter than a word. Computer programming tasks that require bit manipulation include low-level device co...

chineseqsc的博客 296

c语言 字节操作,C语言位操作是什么?

C语言位操作是什么?C语言是一种中级语言,能对计算机硬件直接操作,那么C语言位操作是什么呢,下面小编为你介绍一下吧!一、位的概念我们知道,在计算机中,一字节占8位(现在的某些电脑也有占16位的),这样表示的数的范围为0-255,也即00000000-11111111。位就是里面的0和1。char c=100;实际上c应该是01100100,正好是64H。其中高位在前,低位在后。| |第7位 第0位...

weixin_42516048的博客 608

C 位操作

C语言是一种中级语言,能对计算机硬件直接操作,这就涉及到位的概念。 一、位的概念 我们知道,在计算机中,一字节占8位(现在的某些电脑也有占16位的),这样表示的数的范围为0-255,也即00000000-11111111。位就是里面的0和1。 char c=100; 实际上c应该是01100100,正好是64H。其中高位在前,低位在后。 | | 第7位 第0位 二、位逻辑运算

yove_12的专栏 946

C语言中位操作

一、基本位操作 | | | |-|-|-或-| |-&-|-与-| |-~-|-取反-| |-^-|-异或-| |-<<-|-左移-| |->>-|-右移-| | | | 二、位操作的常见用法 1.获取某位的值 #define BitGet(Number,pos) ((Number)|= 1<<(pos)) //把某位置1 #define BitGet(Number,pos) ((Number) &= ~(1<<(pos)) //把某位

数智技术 1841

位操作、函数和数组

面试题 位操作、函数和数组

seasky的博客 365

c++位操作指令

http://www.programbbs.com/doc/3012.htm一、传统的C方式位操作:1.基本操作:   使用一个unsigned int变量来作为位容器。2.操作符:|   按位或操作符:result=exp1|exp2;当exp1和exp2中对应位中至少有一个为1时,result中对应位为1,否则为0。&  按位与操作符::result=exp1&exp2;当exp1和exp2中对应位全为1时,result中对应位为1,否则为0。^  按位异或或操作符:result=exp1^exp2;当

csw_100的专栏 1152

C语言位操作符详解:从入门到实战应用

与高级语言中的逻辑操作不同,位操作直接作用于数据的二进制表示,因此在系统编程和性能优化中具有不可替代的作用。printf("解压缩后: %d, %d, %d, %d\n", a1, b1, c1, d1);// 结果为0b1000,即8。printf("压缩前: %d, %d, %d, %d\n", a, b, c, d);1. 六种基本位操作符:与(&)、或(|)、异或(^)、取反(~)、左移(<<)、右移(>>)规则:对两个操作数的每一位进行逻辑与操作,只有当两个对应位都为1时,结果才为1,否则为0。

Herbert_hwt的博客 602

java位操作概念和举例

Java 中的位操作是直接对整数的二进制位进行运算的操作,效率极高(因为直接操作内存中的二进制数据)。常用的位操作包括按位与(&)、按位或(|)、按位异或(^)、取反(~)、左移(<<)、右移(>>)、无符号右移(>>>) 等。

weixin_51302377的博客 663
上一篇: 二叉树遍历的常用方法
下一篇: 二分查找及其应用
vcjmhg
博客等级 码龄11年 27粉丝 94原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值