多个数字范围的排列

时间:2011-01-26 13:51:49

标签: c++ vector permutation

我需要从数组中的多个数字范围生成排列。

using namespace std;

int generatePermutations(vector<int> &myVector, vector<vector<int> > &swappable) {
    int i = 0, s = 0;
    for (s = 0; s < swappable.size(); s++) {
        do {
            for (i = 0; i < myVector.size(); i++) {
                printf("%i ", myVector[i]);
            }
            printf("\n");
            swappable.pop_back();
            generatePermutations(myVector, swappable);
        } while (next_permutation(myVector.begin()+swappable[s][0],
                myVector.begin()+swappable[s][1]));
    }
}

int main() {
    vector<int> myArray;
    myArray.resize(6);
    myArray[0] = 0;
    myArray[1] = 1;
    myArray[2] = 2;
    myArray[3] = 3;
    myArray[4] = 4;
    myArray[5] = 5;

    // Swappable positions (0 - first, 1 - last)
    vector<vector<int> > swappable;
    swappable.resize(2);
    swappable[0].resize(2);
    swappable[0][0] = 1; swappable[0][1] = 3;
    swappable[1].resize(2);
    swappable[1][0] = 4; swappable[1][1] = 6;
    generatePermutations(myArray, swappable);

    return 0;
}

上面的示例应该生成如下内容:

0 1 2 3 4 5
0 2 1 3 4 5
0 1 2 3 5 4
0 2 1 3 5 4

但它产生了这个:

0 1 2 3 4 5
0 1 2 3 4 5

3 个答案:

答案 0 :(得分:2)

我认为它可以交换是一组可以交换的范围吗?所以[[1,3],[4,6]]意味着[1,3]中的任何东西(索引1和2)可以在该范围内交换,类似地[4,6]?范围永远不会重叠吗?

How does this look:

typedef vector<vector<int> >::const_iterator SwappableIter;
void generatePermutations(vector<int> &data,
                          SwappableIter begin, SwappableIter end)
{
  if (begin == end) {
    print(data);
  }
  else {
    vector<int>::iterator start = data.begin() + (*begin)[0],
      stop = data.begin() + (*begin)[1];
    sort(start, stop);
    do {
      generatePermutations(data, begin + 1, end);
    } while (next_permutation(start, stop));
  }
}

答案 1 :(得分:0)

以下是您的生成算法的略微修改版本(已损坏)。

int generatePermutations(vector<int> &myVector, vector<vector<int> >& swappable) {
  do
  {
    do
    {
      print(myVector);
      // generate permutations of the second segment
    } while(next_permutation(myVector.begin() + swappable[1][0], myVector.begin() + swappable[1][1]));

    // re-sort the second segment
    sort(myVector.begin() + swappable[1][0], myVector.begin() + swappable[1][1]);

    // calculate permutation of first segment
  } while(next_permutation(myVector.begin() + swappable[0][0], myVector.begin() + swappable[0][1]));
}

编辑:现在修复以生成组合,但仅适用于两个范围,Fred的上述解决方案更具可扩展性。

答案 2 :(得分:0)

您已为该问题创建了一个看似正确的迭代解决方案,但在每次迭代中,您都会从swappable向量中删除一个元素并进行递归调用。
由于myVectorswappable都由非const引用传递,因此这些递归调用会在您实际生成排列之前销毁swappable向量的内容。

只需删除

swappable.pop_back();
generatePermutations(myVector, swappable);

并且代码应该开始工作。