位运算及其oj题

先注意一个点:如果理不清位运算的优先级,就一定要在执行运算时,该带括号的带括号!!!!!

一.基础位运算

x << n:奉行多退少补的原则:假设数据补码长度为8位,将n的二进制下补码 所有位向**左移动n位,并在右边补上n个0。此时统计位数,如果超过8位,则将最左侧超过的几位丢弃。<<**相当于该数十进制下*2^n

eg:

5 << 1 → 101 -> 1010 → 十进制 10(5×2)

5 << 2 → 101 -> 10100 → 十进制 20(5×4)

-2 << 2 -> 1111 1110 -> 111 11000 -> 十进制 -8 (-2 * 4)

x >> n:将n的二进制下补码所有位向右移动n位,并在左边补上n个++符号位!!!++依旧要将右边超位数几位丢弃。>>相当于该数十进制下/2^n

eg:

-8 >> 2 -> 1111 1000 -> 1111 1110 -> 十进制 -2 (-8 / 4)

&,|,^:

~:按位取反。对数据补码的每一位都取反,包括符号位!!

二.给一个数n,确认它二进制的第x位是0还是1

为了方便观察,我们假设将n二进制每一比特位倒置在一个数组里,那么它的下标就代表它是第几位。

随后将n右移x个位置,即把第x个位置移到最后一位,然后再将右移以后的n与1按位与(&),两个数按位与的规则是将两个数化成二进制,每一位一一对应,有0则是0。

假如数据位数为32位:

最终结果为1,则第x位是1。

三.将n二进制表示的第x位修改为1

将x位的数按位或(|)一个1,其余数字要保持不变,就按位或上一个0。要获得满足前面要求的一个数,该怎么办呢?只需将1<<x就行。

随后用n|=(1<<x)即可完成修改。相当于把1挪到第x位,然后再进行按位或。

二三实操:只出现一次的数Ⅱ

https://leetcode.cn/problems/single-number-iihttps://leetcode.cn/problems/single-number-iin是所有数中,除a以外,其余数的种类之和。除a以外其余数均出现三次,因此他们的总数是3n。

注:同一位置指的是同一比特位。

将同一比特位所有数之和%3,得到的结果与a在同一比特位下的值一一对应:

根据以上的信息,我们可以得到算法:

1.求和:实际是求该位下1的个数。

2.用每一位的和分别%3,结果便得到a在同一位下对应的数字,再用取模的结果依次修改ret的每一位,最终ret的每一位就表示a的二进制下的每一位。就得到了a。

3.求和和修改操作就用到了二,三两个小巧思。其中求和的思想是先确认第i位的数是0是1,如果是1,就++sum,以达到统计1个数的目的。而修改操作则是在ret初始值为0的前提下,假如确定第i位a所对应的数字位1,也就是和模3的值为1,就把ret第i位的值改为1。

复制代码
class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret = 0;
        for(int i = 0;i < 32;i++)//遍历int每一位,并完成ret的修改。
        {
          int sum = 0;//统计每一位所有数之和。
          for(auto e: nums)//求nums里所有数第i位的和
          {
            if(((e >> i) & 1) == 1) 
            sum++;
          }
          sum %= 3;
          if(sum == 1) ret |= 1 << i;//修改
        }
        return ret;
    }
};

其实我们可以设计通法,n个数相同,在求和取模的时候就模n

四.将一个数n的二进制数表示的第x位修改为0

**将n的二进制形式&上一个除了第x位是0,其余位均为1的二进制数。**那么怎么保证该二进制数,除了第x位是0,其余全为1呢?

答案是将1左移(<<)x位的结果取个反(~)就行了:

五.lowbit

注意:-n是先对n按位取反,然后再加1的成果。

六.干掉n二进制表示中最右侧的1

n-1时,会去前面的位借位,一直借到最右边的那个1处停止,此时最右边的1就会因借位变成0。

本质:

七.异或(^)操作的运算率

注意:异或玩的就是不进位相加。然后它满足交换律和结合率。

相关推荐
渡我白衣1 小时前
深入理解 Transformer:Decoder与Masked_Attention
linux·服务器·网络·c++·人工智能·深度学习·transformer
励志不掉头发的内向程序员1 小时前
【从零写一个CAD 04】中键拖动平移:抓住一个点,让它一直待在鼠标底下
开发语言·c++·qt·学习·系统架构·计算机外设
UIU1141 小时前
同一个变量在两个 .c 文件里类型不一致,程序会怎样?
c++·学习·c#
weixin_4241836110 小时前
开放—封闭原则实战(下):基于策略的流程编排与编译期多态
c++·分布式·系统架构
wuminyu10 小时前
C++协程实现接收端的零拷贝Buffer管理原理剖析
java·linux·c语言·jvm·c++
小蒋学算法10 小时前
算法-交替删除操作后最后剩下的整数-跟着灵茶山艾府学算法
数据结构·算法
m0_3807438710 小时前
C++中的freopen的用法实例详解
开发语言·c++
荆棘鸟智能11 小时前
林业遥感长势评估怎么做?从NDVI时序分析到LiDAR蓄积量回归
人工智能·算法·智慧林业
jimy111 小时前
polymorph.cpp里面的“析构函数、智能指针”问题
开发语言·c++