组合是一个计数概念。从 n n n 个不同元素中取出 m m m( m < = n m<=n m<=n)个元素组成一组,不考虑其元素的顺序,叫做从 n n n 个不同元素中取出个 m m m 元素的一个组合。例如,从A、B、C三个元素中取出两个元素的组合有AB、BC、AC,这里AB和BA被视为同一种组合,因为组合不考虑元素的顺序。
使用整数表示一种组合。整数的二进制表示的某一位为1,表示该位对应的数被选中,反之为0表示未选中。例如,从0 - 5这6个数中选出3个,则0b111000代表选中3, 4, 5三个数, 0b011001代表选中0, 3, 4三个数。按组合对应的整数由大到小的顺序,求出组合 c 的下一个组合。
#include<bits/stdc++.h> //万能头文件
using namespace std;
//找到c最低位的1所在的位置。
int intlow2(int c) {
return ((((c - 1) ^ c) + 1) >> 1);
}
//同上相同功能代码
//int intlow2(int c) {
// int position = 0;
// while ((c & 1) == 0) {
// c >>= 1;
// position++;
// }
// return 1 << position;
//}
int zuhe_next_incur(int c, int n, int l) {
//当n==1时,直接返回c,因为如果只有一个元素,组合就是它本身
if (n == 1) return c;
if ((c & (1 << l)) == 0) { //如果c的二进制表示中从右数第 l + 1 位是 0
int d = intlow2(c); //找到c最低位的1所在的位置。
c = (c & ~d); //将c中d所对应的位清 0
c = (c | (d >> 1)); //将d右移 1 位后的值与c进行按位或操作,更新c的值
} else {
c = (c & ~(1 << l)); //将c的二进制表示中第l位清 0。
c = zuhe_next_incur(c, n - 1, l + 1); //递归调用自身,减少n的值并增加l的值。相当于n-1个数中选m个
int d = intlow2(c);
c = (c | (d >> 1));
}
return c;
}
int zuhe_next(int c, int n, int m) {
return zuhe_next_incur(c, n, 0);
}
int main() {
//给出当前的组合c=56,求下一个组合
int c=56, n=6, m=3;
while(c){
cout<<c<<" "<<bitset<6>(c)<<endl; //输出组合c的值以及对应的二进制形式,查看具体选了那些数
c = zuhe_next(c, n, m);
}
return 0;
}
输出结果如下