组合算法:开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标代表的数被选中,为0则没有选中。
首先初始化,将数组前n个元素置1,表示第一个组合为前n个数;然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为“01”组合,同时将其左边的所有“1”全部移动到数组的最左端;当第一个“1”移动到数组的m-n位置,即n个“1”全部移动到最右端时,就得到了最后一个组合。
例如求5中选3的组合:
1 1 1 0 0 //1, 2, 3
1 1 0 1 0 //1, 2, 4
1 0 1 1 0 //1, 3, 4
0 1 1 1 0 //2, 3, 4
1 1 0 0 1 //1, 2, 5
1 0 1 0 1 //1, 3, 5
0 1 1 0 1 //2, 3, 5
1 0 0 1 1 //1, 4, 5
0 1 0 1 1 //2, 4, 5
0 0 1 1 1 //3, 4, 5
void output1(int value[], char* middle, int length)
{for(int i=0; i<length; i++){if(middle[i] == '1'){printf("%d ", value[i]);}}printf("\n");
}bool find10(char* middle, int M, int* index)
{bool find = false;for(int i=0; i<M; i++){ if (middle[i] == '1' && middle[i + 1] == '0'){*index = i;find = true;break;}}return find;
}void move1(char* middle, int index)
{int count = 0;for(int i=0; i<index; i++){if (middle[i] == '1'){swap(middle[count++], middle[i]);}}
}//从M 个数中取 N 个数的组合
void enumkind(int value[], int M, int N)
{char *middle = new char[M + 1];middle[M] = '\0';memset(middle, '1', N);memset(middle + N, '0', M - N);printf("%s: ", middle);output1(value, middle, M);int index = 0;while(find10(middle, M, &index)){swap(middle[index], middle[index+1]);move1(middle, index);printf("%s: ", middle);output1(value, middle, M);}delete middle;
}int _tmain(int argc, _TCHAR* argv[])
{int value[5] = {1,2,3,4,5};enumkind(value, sizeof(value)/sizeof(int), 4);getchar();return 0;
}