【问题标题】:Efficient algorithm to get all binary combinations with k 1s用 k 1s 获得所有二进制组合的高效算法
【发布时间】:2020-12-30 20:54:24
【问题描述】:

我有 n 个位,我知道其中有 k 个位。
我应该从 n = 4 和 k = 2 的算法中得到的结果是:

1100
1010
1001
0110
0101
0011

我已经尝试了一些递归策略,但它们都不足以满足我的需求(n 可能 > 50000)。
我也看过类似问题的答案,但效率不够。

我认为通过利用 1 和 0 没有区别这一事实,我可以让某些东西快速运行,这样我就可以避免产生相同结果的大量迭代。
同样,我注意到我可以避免计算多达一半的结果,因为它们中的大多数只是彼此相反的二进制(即 1100 -> 0011)。

【问题讨论】:

  • n 可能高达 50000... 当您弄清楚可能有多少时,说“得到所有”并没有什么意义。你确定你的意思不是“计数”。
  • 当 n = 50,000 时,你的 k 值是多少?在那个大小下,即使是一个适度的 k 也可能有数量惊人的组合。
  • 通常 k 略小于值的一半,所以如果 n 为 50,000,通常 k 为 20,000 或类似值。
  • 祝你好运,处理这些数字的输出。你知道代表多少位模式吗?想想宇宙中的原子数量......当你的 输出 将有一个巨大的大小时,效率还不够好。对于 n = 50000, k = 6,位模式的数量为 1084657180984679023259666700000。由于每个模式有 50000 位,因此我们谈论的不仅仅是6 billion yottabyte
  • 复杂度不能低于得到数字的个数,C(n, k)

标签: algorithm performance binary


【解决方案1】:

在 C++ 中,您可以使用 std::next_permutation,不过您应该找到 std::string 以外的其他内容作为您的类型。

#include <algorithm>
#include <string>
#include <iostream>
void Permute(int n = 8, int k = 3) {
    std::string s = std::string(n-k, '0')+std::string(k, '1');
    do {
        std::cout << s << '\n';
    } while(std::next_permutation(s.begin(), s.end()));
}

00000111
00001011
00001101
00001110
00010011
00010101
00010110
00011001
00011010
00011100
00100011
00100101
00100110
00101001
00101010
00101100
00110001
00110010
00110100
00111000
01000011
01000101
01000110
01001001
01001010
01001100
01010001
01010010
01010100
01011000
01100001
01100010
01100100
01101000
01110000
10000011
10000101
10000110
10001001
10001010
10001100
10010001
10010010
10010100
10011000
10100001
10100010
10100100
10101000
10110000
11000001
11000010
11000100
11001000
11010000
11100000

【讨论】:

    猜你喜欢
    • 2013-02-02
    • 2018-01-03
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    • 2013-01-15
    • 1970-01-01
    相关资源
    最近更新 更多