【情况一,不存在重复数】
实现机理:先创建一个字符串数组,其下标表示 1 到 n 个数,数组元素的值为1表示其下标代表的数被选中,为0则没选中。
然后初始化,将数组前 m 个元素置 1,表示第一个组合为前 m 个数。
然后从左到右扫描数组元素值的 10 组合,找到第一个 "10" 后交换 1 和 0 的位置,变为 01,而后将该10组合前的1和0重新组合(1放在前边,其个数为10组合前1的个数,0放在后边,其个数为10前0的个数,而后接10的倒转组合 01)。当m 个 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
实现机理:先创建一个字符串数组,其下标表示 1 到 n 个数,数组元素的值为1表示其下标代表的数被选中,为0则没选中。
然后初始化,将数组前 m 个元素置 1,表示第一个组合为前 m 个数。
然后从左到右扫描数组元素值的 10 组合,找到第一个 "10" 后交换 1 和 0 的位置,变为 01,而后将该10组合前的1和0重新组合(1放在前边,其个数为10组合前1的个数,0放在后边,其个数为10前0的个数,而后接10的倒转组合 01)。当m 个 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
可以发现,这时候组合问题可以用排列问题同样的策略解决!
假设10中选5.
int data[10] = {1,2,3,4,5,6,7,8,9,10};
int array[10] = {0,0,0,0,0,1,1,1,1,1}; //初始选最后5个!以后移动数据每次找出刚刚比这个数大的数字!
do
{
cout<<"[combination]="
for(int i = 0; i < 10; ++i)
{
if(array[i] != 0 )
cout<<setw(5)<<data[i];
}
cout<<endl;
} while(std::next_permutation(array,array+10);
===============================================================
【情况一,不存在重复数】
如 2,2,3,3,5,5,5 中选3个数
x x x
2进制 2进制 3
进制
对应2 对应3 对应3
int data[7] = {2,2, 3,3, 5,5,5};
in step[] = {2,3,3}; //进制
int array[3]={0, 0, 3}; // 初始状态
-> 0 1 2 -> 0 2 1 -> 1 0 2
-> 1 1 1 -> 1 2 0 -> 2 0 1
-> 2 1 0 ->
这时,这个next_permutation()就要自己写啦!
bool next_permutation(int* pbegin, int * pend,
int* jinzhi, int num)
{
// 依据上面思路,写next_permutation()函数!
}