C++位运算:通过二进制保存信息

这几天遇到了一种特殊的动态规划—-数位DP。做的我头痛欲裂,连忙过来写一篇有关位运算的文章,看看它的神奇之处。

在C++中有”与&、或|、非~、异或^、右移>>、<<左移”这六种运算符。但实际在二进制的算法中远不止这些。


1.0 基本运算

1.1 运算前提

使用二进制保存信息,代表这是一个集合,而不是该二进制的真实数字,例如101,在这里代表的是集合{0, 2},而不是5

1.2 空集、单元集、全集和补集(初始化)

  • 空集 ∅ 就是全空,也就是 res = 0;
  • 单元集,即单个元素的集合,例如我需要 4 ,也就是 10000,只需要 res = 1 << 4; 即可
  • 全集,指的是从 0 到指定数字的所有元素,res = (1 << n) - 1; 可以获取从 0 ~ n – 1 的所有元素
  • 补集,把 s 在指定数字内所有欠缺元素指出,res = ((1 << n) - 1) ^ s;

1.3 属于与不属于(检查元素是否在s中)

res = (s >> i) & 1; res为 1 是属于,为 0 便是不属于。

1.4 添加/删除元素

  • 添加元素,往 s 中添加元素 i res = s | (1 << i);
  • 删除元素,删除 s 中的元素 i(可能不在集合 s 中)res = s &~ (1 << i);
  • 删除元素,删除 s 中的元素 i(一定在集合 s 中)res = s ^ (1 << i);

2.0 进阶运算

2.1 计算集合大小

即计算 s 中 1 的数量,使用C++内置复杂度为 O( 1 ) 函数。res = __builtin_popcount(s);

2.2 计算二进制长度

res = __lg(s) + 1; 注意lg(0)是非法行为

2.3 集合最大元素

res = __lg(s);

2.4 lowbit(集合最小元素)

lowbit,顾名思义就是获取最小(最右边的 1 )的元素,lowbit(s) = s & ~s;

例如 s = 1010,在lowbit运算之后就是 0010,获取了最右边的 1 元素所在的位置

在C++内置函数中,也可以使用 res = __builtin_ctz(s);

2.5 删除lowbit元素

删除最小的元素,其他保持不变。delete(s) = s & (s - 1);


3.0 遍历与枚举

3.1 遍历集合

for(int i = 0; i < n; i ++){
    if((s >> i) & 1){
        // 处理 s
    }
}

3.2 枚举全集

for(int s = 0; s < (1 << n); s ++) {
    // 处理 s
}

3.3 枚举非空子集

for(int sub = s; sub; sub = (sub - 1) & s) {
    // 处理 sub
}

3.4 枚举含空子集

int sub = s;
do {
    // 处理 sub
    sub = (sub - 1) & s;
} while (sub != s);

3.5 枚举超集

如果 T 是 S 的子集,那么称 S 是 T 的超集(superset)。

for (int s = t; s < (1 << n); s = (s + 1) | t) {
    // 处理 s
}

4.0 总结

首先是资料整理的来源,部分内容来自于网络收集,3.0的内容借鉴了灵茶山艾府的整理。

整理的过程中,我确实理解到了二进制的妙处。接触位运算的感觉其实就是”简单 -> 好难 -> 不想学 -> 有点意思 -> 悟了”的过程。所以如果无法理解大佬解释的话,就先打好基础,了解用途,然后再去慢慢理解就好辣~

有兴趣的话可以观看我的以往文章(还没多少欸)。博客还在持续更新中,敬请期待~


作 者:雪崩了...
链 接: https://bolinio.top/?p=158
来 源:bolin的技术厨房
版 权 声 明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0许可协议。文章版权归作者所有,未经允许请勿转载!


暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇