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;
}
}
}
http://should.blogbus.com/logs/3561496.html