n and m: C(n, m)
position: 组合中的第几位
取 1~n 个数中 m个数的组合:
思路:将所有组合按照升序排列,则每个组合的各个元素满足:
Ci <= n - m + i ( i = 1, 2, ... m )
且每个位置元素的起始值为前一个起始值+1。
*/
void combination1( int n, int m, int position, int start, int *rst ) {
if( position == m ) { // 最后一位
for( int i = start; i <= n; i++ ) {
rst[position - 1] = i;
print( n, m, rst);
}
return;
}
for( int i = start; i <= n - m + position; i++ ) {
rst[position - 1] = i;
combination1( n, m, position + 1, i + 1, rst );
}
}
/*
基本思路与combination1一样
*/
void combination2( int n, int m, int *src, int *dest ) {
for( int i = n; i >= m; --i ) {
dest[m - 1] = src[i - 1];
if( m > 1 )
combination2( i - 1, m - 1, src, dest );
else {
for( int i = 0; i < 2; i++ )
cout << dest[i] << " ";
cout << dest[2] << endl;
}
}
}
/*
利用二进制位求组合C(n, m)
目前实现的是 从 1~ n个数中,取 m个数的组合
可适当修改 if( num == m ),来求解更多组合问题(如C(n, 0) ~ C(n, m)所有的组合)
*/
void combination3( int n, int m, int dest[] ) {
unsigned int upperBound = 1 << n;
int num = 0;
for( unsigned int i = 1; i < upperBound; i++ ) {
unsigned int t = 1, offset = 0;
num = 0;
while( t <= i ) {
t = 1 << offset;
if( t & i ) {
dest[ offset ] = offset + 1;
num++;
} else {
dest[ offset ] = -1;
}
offset++;
}
//print
if( num == m ) {
for( int j = 0; j < offset - 1; j++ ) {
if( dest[ j ] != -1 )
cout << dest[ j ] << " ";
}
cout << endl;
}
}
}