如何在C ++中使用替换创建排列?

时间:2013-01-27 02:16:01

标签: c++ algorithm permutation

注意:在阅读了templatetypedef的帖子后,似乎我正在尝试计算一组自相应的笛卡尔积。

我不能完全确定我想要解决的问题是什么,但它似乎非常接近于替换我的排列。

所以基本上,我的问题是这个。 给定一个数组,例如:

{1, 2, 3}

和一个大小,比如2。 我需要输出:

{1,1},{1,2},{1,3},{2,1},{2,2},...

如果大小为3,那么它将是

{1,1,1},{1,1,2},{1,1,3},{1,2,1},{1,2,2},{1,2,3},{1,3,1}...

我该怎么做?

出于我的问题的目的,我的输入大小为15个数字,所以我想我可以创建15个for循环,但这对我来说似乎是一个黑客。

感谢。

编辑:在我不确定我在问什么以及我实际需要的内容基本上是同样的问题后,我编辑了我的问题。 在阅读了templatetypedef的帖子后,似乎我正在尝试计算一组自相应大小的笛卡尔积。

1 个答案:

答案 0 :(得分:2)

你试图计算集合{1,2,3}的Cartesian product本身十五次。您可以使用简单的递归算法非常优雅地完成此任务:

  • 要计算一次只有一次的集合的笛卡尔积,请返回一个包含原始集合中每个元素的单一列表的集合。
  • 计算具有自身n的集合的笛卡尔积。 1次:
    • 递归计算集合的笛卡尔乘积n - 1次。
    • 对于输入列表的每个元素x:
      • 到目前为止生成的每个序列S:
        • 将序列S + x添加到输出集。
    • 返回输出集。

(有点低效)C ++代码:

vector<vector<int>> CartesianPower(const vector<int>& input, unsigned k) {
    if (k == 1) {
        vector<vector<int>> result;
        for (int value: input) {
            result.push_back( {value} );
        }
        return result;
    } else {
        vector<vector<int>> result;
        vector<vector<int>> smallerPower = CartesianProduct(input, k - 1);

        for (int elem: input) {
            for (vector<int> sublist: smallerPower) {
                sublist.push_back(elem);
                result.push_back(sublist);
            }
        }

        return result;
     }
}

希望这有帮助!