组合数

写组合数:从{1,2,3,4,5}中选3个数,输出所有组合。然后扩展到从n个数中选m个数。

1、动态规划——递归

我们只需从5个数当中任选一个,然后再在剩下的4个元素中选两个;如果在剩下的4个元素中选一个,则最后再再剩下三个元素中选两个。

具体过程:

a、我们从5个元素中任选一个,然后与第0位交换;

b、我们从剩下的4个元素中任选一个,然后与第1位交换;

c、在最后的3个元素中任选一个,输出这三个元素,结束。

注意:记得还原数组,否则出错。

上程序:

#include <iostream>


void getGroup(int array[], const int size, int numSelected, const int sum);

int main(int argc, const char * argv[]) {

    // insert code here...

    std::cout << "Hello, World!\n";

    int array[] = {1,2,3,4,5};

    getGroup(array, 5, 0, 3);

    return 0;

}


void getGroup(int array[], const int size, int numSelected, const int sum)

{

    if (numSelected == sum)

    {

        for (int i=0; i<sum; ++i)

        {

            std::cout<<array[i]<<' ';

        }

        std::cout<<std::endl;

        return;

    }

    for (int i=numSelected; i<size; ++i)

    {

        std::swap(array[numSelected], array[i]);

        getGroup(array, size, numSelected+1, sum);

        std::swap(array[i], array[numSelected]);

    }

}


结果:

1 2 3 

1 2 4 

1 2 5 

1 3 2 

1 3 4 

1 3 5 

1 4 3 

1 4 2 

1 4 5 

1 5 3 

1 5 4 

1 5 2 

2 1 3 

2 1 4 

2 1 5 

2 3 1 

2 3 4 

2 3 5 

2 4 3 

2 4 1 

2 4 5 

2 5 3 

2 5 4 

2 5 1 

3 2 1 

3 2 4 

3 2 5 

3 1 2 

3 1 4 

3 1 5 

3 4 1 

3 4 2 

3 4 5 

3 5 1 

3 5 4 

3 5 2 

4 2 3 

4 2 1 

4 2 5 

4 3 2 

4 3 1 

4 3 5 

4 1 3 

4 1 2 

4 1 5 

4 5 3 

4 5 1 

4 5 2 

5 2 3 

5 2 4 

5 2 1 

5 3 2 

5 3 4 

5 3 1 

5 4 3 

5 4 2 

5 4 1 

5 1 3 

5 1 4 

5 1 2 


如果只是就组合,不要求顺序的话,如下程序:

#include <iostream>


void getGroup(int array[], const int size, int pos, int numSelected, const int sum);

int outArray[3]={0};

int main(int argc, const char * argv[]) {

    // insert code here...

    std::cout << "Hello, World!\n";

    int array[] = {1,2,3,4,5};

    

    getGroup(array, 5, 0, 0, 3);

    return 0;

}


void getGroup(int array[], const int size, int pos, int numSelected, const int sum)

{

    if (numSelected == sum)

    {

        for (int i=0; i<sum; ++i)

        {

            std::cout<<outArray[i]<<' ';

        }

        std::cout<<std::endl;

        return;

    }

    for (int i=pos; i<size; ++i)

    {

        outArray[numSelected] = array[i];

        getGroup(array, size,i+1, numSelected+1, sum);

    }

}

结果:

1 2 3 

1 2 4 

1 2 5 

1 3 4 

1 3 5 

1 4 5 

2 3 4 

2 3 5 

2 4 5 

3 4 5 


2、非递归

对于固定个数的情况,非递归还是挺简单的。具体过程如下:

a、执行3次循环,每次选择一个数

b、比较这三个数,如果下标各不同,则输出。

上程序:

#include <iostream>

void getGroup(int array[], const int size);

int main(int argc, const char * argv[]) {

    // insert code here...

    std::cout << "Hello, World!\n";

    int array[] = {1,2,3,4,5};

    getGroup(array, 5);

    return 0;

}


void getGroup(int array[], const int size)

{

    for (int i=0; i<size; ++i)

        for (int j=0; j<size; ++j)

            for (int k=0; k<size; ++k)

            {

                if (i!=j && i!=k && j!=k)

                {

                    std::cout<<array[i]<<' '<<array[j]<<' '<<array[k]<<std::endl;

                }

            }

}


如果只是就组合,不要求顺序的话,如下程序:

#include <iostream>

void getGroup(int array[], const int size);

int main(int argc, const char * argv[]) {

    // insert code here...

    std::cout << "Hello, World!\n";

    int array[] = {1,2,3,4,5};

    getGroup(array, 5);

    return 0;

}


void getGroup(int array[], const int size)

{

    for (int i=0; i<size-2; ++i)

        for (int j=i+1; j<size-1; ++j)

            for (int k=j+1; k<size; ++k)

            {

                if (i!=j && i!=k && j!=k)

                {

                    std::cout<<array[i]<<' '<<array[j]<<' '<<array[k]<<std::endl;

                }

            }

}


结果:

1 2 3

1 2 4

1 2 5

1 3 4

1 3 5

1 4 5

2 3 4

2 3 5

2 4 5

3 4 5



3、二进制组合

如果只是求组合,不要求顺序的话,那么我们可以考虑二进制组合。

5选3,

00000——11111

一共是2^5=32种,选择有三个1的便是所求。

如11100就是123;10110就是134。

如何确定是1还是2还是5呢?

假设BinaryArray是00000到11111。我们设firstIndex = 0x01 & BinaryArray,如果firstIndex等于1说明选择了1,若为0说明没有选择;其他也是如此,如3,我们社thirdIndex = 0x07(0000 0100) & BinaryArray,如果thirdIndex等于1说明选择了3,若为0说明没有选择。

比较简单,不再赘述。


延伸:扩展到从n个数中选m个数呢?

如果用递归的话比较容易解决,换一下参数就行了。

不用递归的话可以考虑用二进制组合的方法。

如果这两种方法都不用,是否还用其他方法呢?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值