二进制子集生成与排列组合
咳咳,二进制我觉得很有必要单独列出来,二进制的玩法还是很多的,比较多的就是表示多重状态,因为只有1和0的存在,每一位可以表示可取或者不可取,还能配合排列组合使用,来试试。
- 首先,我们来搞搞排列,列出n个数的全排列。
- 这里我们有三种方法去搞定。想不到吧。
- 首选当然是强大的STL提供的next_permutation函数,直接下一次排列。
- 当然,除了下次排列,还有上次排列函数:perv_permutation(a,a+n);
- 如果自己来写呢,我们可用递归回溯的方式写出来。
- 对于每一组数列呢,每个元素都排在最前面。所以第一次循环就是一号元素要是每一个元素,后面swap换了之后要换回来,方便下一次的互换。
- 这是排列,那组合怎么搞呢,比如,我5个里面只要取3个,怎么搞。
- 也很简单呀,排列的输出判断条件是begin等于end,而组合不需要输出全部,所以只要把end设置为我们需要取的数,便可以了
- 咳咳,咱不是讲二进制的满,怎么讲了这么多排列呢,害。
- 接下来我们想想,如果题目不需要输出全排列,而是输出他的组合,就是他的子集(子集内部的元素无顺序之分),那该怎么办呢?
- 我们知道,子集就是取或者不取的所有可能集合,那么取我就用1表示,不取我就用0表示,这刚刚好符合我们的二进制,一个数的子集,一共有2n种情况。
- 那么怎么写呢?在此之前,我们得认识几个操作符
1. 与运算符(&)
- 二元操作符,操作两个二进制数据;两个二进制数最低位对齐,只有当两个对位数都是1时才为1,否则为0
int a = 3 & 2 ;
cout << a << endl; //结果为 2
3的二进制补码表示为:
00000000 00000000 00000000 00000011
2的二进制补码表示为:
00000000 00000000 00000000 00000010
运算:3 & 2
00000000 00000000 00000000 00000011
& 00000000 00000000 00000000 00000010
-------------------------------------------
00000000 00000000 00000000 00000010 二进制是2
2. 或运算符(|)
- 二元操作符,操作两个二进制数据;两个二进制数最低位对齐,当两个对位数只要有一个是1则为1,否则为0
int a = 3 | 2 ;
cout << a << endl; //结果为 3
3的二进制补码表示为:
00000000 00000000 00000000 00000011
2的二进制补码表示为:
00000000 00000000 00000000 00000010
运算:3 | 2
00000000 00000000 00000000 00000011
| 00000000 00000000 00000000 00000010
-------------------------------------------
00000000 00000000 00000000 00000011 该补码对应十进制为3
3. 异或运算符(^)
- 二元操作符,操作两个二进制数据;两个二进制数最低位对齐,只有当两个对位数字不同时