【问题标题】:c++ combinatoricsC++ 组合学
【发布时间】:2012-04-07 11:52:53
【问题描述】:

我需要 c++ 代码,它会生成所有可能的组合 (n,k) 和重复 其中 n - 输入数组中的整数个数。 k - 位置数

例如 输入:

n = [1 2 3];
k = 2;

输出:

A3 =

     1     1
     1     2
     1     3
     2     1
     2     2
     2     3
     3     1
     3     2
     3     3

谢谢。

【问题讨论】:

  • 我找到了没有重复的组合代码,当然可以编辑此代码,甚至可以从头开始编写代码。但我寻找快速解决方案,可能在某种标准库中实现,我不想深入研究实现细节。
  • 你搜索堆栈溢出了吗?我发现这似乎是你想要的:stackoverflow.com/questions/9430568/…

标签: c++ permutation combinations combinatorics


【解决方案1】:

使用standard library:

do {
    for(int i = 0; i < k; i++){
        std::cout << n[i];
    }
    std::cout << '\n';
} while (std::next_permutation(n, n + k));

【讨论】:

  • @Rahat.Zamhan 什么不起作用?它对我有用。你能举一个代码例子,它不能按预期工作吗?
  • 你没有初始化变量i
【解决方案2】:

在这里查看我的答案:

PHP take all combinations

它是 PHP;但是这个概念(递归等)应该很容易“翻译”......

【讨论】:

    【解决方案3】:

    这基本上是以 n-1 为底数(每个数字位移 1),请尝试以下操作:

    编辑:使用vector 而不是new[]delete[]

    #include <vector>
    
    void generatePerms(int n, int k)
    {
        vector<int> perms(k, 1);
    
        //iterate through all permutations
        bool done;
        do {
            //Do something with the current permutation, for example print it:
            for (int i = 0; i < k-1; i++)
                cout << perms[i] << ", ";
            cout << perms[k-1] << endl;
    
            /*
             * Increment last digit first - if it's to big, reset to 1 and
             * carry one (increment next digit), which may also carry one etc.
             *
             * If all digits caused a carry, then the permutation was n, n, ..., n,
             * which means, that we can stop.
             */
            done = true;
            for (int i = k-1; i >= 0; i--) {
                if (++perms[i] > n) {
                    perms[i] = 1;
                    continue;
                } else {
                    done = false; //not all digits caused carry
                    break;
                }
            }
        } while (!done);
    }
    

    【讨论】:

    • @DeadMG 你能解释一下为什么这很糟糕以及应该怎么做吗?
    • @DeadMG 因为当k 不是恒定的(C++ 没有VLA)时不能使用int perms[k],因此使用vector 是矫枉过正。也可以说就地工作也是不可取的 - 抱歉,我没有得到你的反对意见:/
    • @Griwes 嗯.. 我想我明白了你的意思; vector 会在自己之后自动清理,即使(尤其是)引发异常也是如此。来自 Java 和 C 的我仍然觉得对所有内容都使用向量并不“正确”,尤其是在像这样的非常小的代码片段中,只要一瞥就可以发现错误。跨度>
    • @Anthales,但它并没有真正花费你任何东西。并且vector 既优于 VLA 也优于动态数组,并且仅用于使用,即使在像这样的非常小的代码片段中也是如此......
    猜你喜欢
    • 1970-01-01
    • 2019-05-19
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多