输出组合数,但是不使用递归

输出组合数,但是不使用递归

众所周知,在应用中递归容易导致各种各样的问题,这里给出了一种不使用递归输出组合数的方案。

这里的「组合数」就是 C m n C_m^n Cmn 对应的所有组合。例如 C 4 2 C_4^2 C42 对应了 6 6 6 种组合如下

0 1
0 2
0 3
1 2
1 3
2 3

人在书写组合数的时候是按照顺序书写的,同样地,利用这种顺序性,给定一个组合,程序可以计算下一个组合是什么,仍然以上面的例子来说,我们将组合看成从 0 0 0 3 3 3 中挑选数字的过程,上面的组合可以看作如下的挑选过程

0*	1*	2	3
0*	1	2*	3
0*	1	2	3*
0	1*	2*	3
0	1*	2	3*
0	1	2*	3*

注意到如果某一组合挑选了最后的连续若干个数,那么下一组合就是将这连续若干个挑选的数整体向前挪移的过程。

建议读者自己举几个例子更好理解。

以下给出程序

#include <iostream>

template<std::size_t N, std::size_t M>
void next(std::size_t array[N]) {
    std::size_t nj = N;
    while (array[nj - 1] == M - (N - nj) - 1) {
        --nj;
    }
    ++array[nj - 1];
    for (std::size_t off = nj; off < N; ++off) {
        array[off] = array[nj - 1] + (off - (nj - 1));
    }
}

constexpr std::size_t comb_num(std::size_t N, std::size_t M) {
    std::size_t ret = 1;
    for (std::size_t i = 0; i < N; ++i) {
        auto j = N - 1 - i;
        ret *= (M - j);
        ret /= (N - j);
    }
    return ret;
}

template<std::size_t N, std::size_t M>
void print() {
    static_assert(M >= N);

    std::size_t array[N];
    for (std::size_t i = 0; i < N; ++i) {
        array[i] = i;
    }

    for (std::size_t i = 0; i < comb_num(N, M); ++i) { // C(3, 6)
        for (std::size_t j = 0; j < N; ++j) {
            std::cout << array[j] << ' ';
        }
        std::cout << std::endl;
        next<N, M>(array);
    }
}

int main() {
    print<4, 10>();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值