You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
/*
二进制数的子集数量计算
子集指的是在原二进制数中1的选择, 假设对应的二进制数中有数字1共n个, 那么最少选择1个, 最多选择n-1个, 请找出所有的这样的二进制数子集。
比如二进制数13=(1101)b, 有3个位置存在数字1,
那么:
包含1个1的: 1000,0100,0001
包含2个1的: 1100,1001,0101
共6个
*/
// 输出十进制对应的二进制数(模板)
void print ( int n ) {
printf ( " %2d: " , n ) ;
// 输出4个数位的二进制数
for ( int i = 3 ; i > = 0 ; i - - ) // 由高到低位
printf ( " %d " , n > > i & 1 ) ;
puts ( " " ) ;
}
/*
输出n的所有二进制子集
方法1: 逻辑清晰, 但性能差
理解一下:
(1) i=n-1:显然, 子集不包含自身, 也就是最大是比自己小1的才可能是第一个最大子集
(2) for (int i = n - 1; i; i--),从可能的最大子集开始,一个个减少,当然可以遍历到每个可能的子集
(3) if ((i & n) == i) 这个位运算, 就是通过数位上数字1的与运算, 只有超集与之相与, 才能保证得到自身, 挺好理解
*/
void sub1 ( int n ) {
for ( int i = n - 1 ; i ; i - - )
if ( ( i & n ) = = i ) print ( i ) ;
}
/*
方法2: 优化
*/
void sub2 ( int n ) {
for ( int i = n - 1 ; i ; i = ( i - 1 ) & n )
print ( i ) ;
}
int main ( ) {
int st = 13 ; // 1101
sub1 ( st ) ;
printf ( " ================================== \n " ) ;
sub2 ( st ) ;
return 0 ;
}