二进制枚举

目录

  • 一、按位运算符
    • 1. 移位运算符
    • 2. 逻辑按位运算符
  • 二、按位运算符实现二进制和十进制转换
  • 三、二进制的枚举
    • 1. 枚举集合{0,1,2,……,n-1}
    • 2.枚举集合的子集

一、按位运算符

1. 移位运算符

value<<shift//向左移动
value>>shift//向右移动

value是被操作的整数值,shift是要移动的位数

举个栗子:
int 13<<3
二进制枚举_第1张图片
int 13>>3
二进制枚举_第2张图片

注:

  • 腾出的位置用0填充,超出边界的位置被丢弃
  • 每一位是前一位的2倍,因此每左移一位相当于乘2,左移n位相当于乘2^n
  • C++左移运算符生成一个新值,不修改原来的值

2. 逻辑按位运算符

①位非运算符(~),将每一位转化为它的反面(1转化而为0,0转化为1)
②OR(|),被操作的两个值得对应位至少有一个1,则新值为1,否则为0
③AND(&),被操作的两个值对应位都为1,则新值为1,否则为0
④XOR(^),一个为1,一个为0则新值为1,否则为0

注:

  • 这里的位均对于二进制数来说的

二、按位运算符实现二进制和十进制转换

对于一个以1和0组成数组,可以看做二进制数,继而可以表示成十进制整数
二进制枚举_第3张图片
那如何将一个十进制数,填加到一个数组中呢:这里需要用到按位运算符

举个栗子:
将20转化为二进制数,并存放在数组中
二进制枚举_第4张图片

三、二进制的枚举

1. 枚举集合{0,1,2,……,n-1}

假设有4个商品,每个商品有挑选或者不挑选两种选择,我们用1表示选择,0表示不选择
如图对应其中一种方案:
二进制枚举_第5张图片
那么,如何枚举一个出所有方案呢:
我们假设这是二进制数,那么这个二进制数最大为1111不超过1<<5或2^5,于是不断缩小这个数就可以列举出所有的方案

#include"iostream"
#include"stdlib.h"
using namespace std;

int main() {
	int x[4];
	for (int i = 0; i < 1 << 4; i++) {
		memset(x, 0, sizeof(x));
		for (int j = 0; j < 4; j++) {
			x[j] = i >> j & 1;
			cout << x[j];
		}
		cout << endl;
	}

	system("pause");
}

程序结果:
二进制枚举_第6张图片

注:

  • 此种方法只是相对于多重循环来说,更方便,但依然是采用枚举的方式,因此只适用于枚举方案较少的情况

2.枚举集合的子集

假设一个 集合sup:01101,这里要将01100或00100等子集sub枚举出来,这里不能像上面那样将sup-1直到0全部枚举出来,因为有的集合并不是sup的子集。

例如:
01011=01101-2 但01001并不是01101的子集
解决方法: 将sub&sup
这里01011&01101=01001,01001就是sup的子集了
因 为 &保证了sup不为0的地方在sub中也不会为0

你可能感兴趣的:(二进制枚举)