C++ 多个数域的置换

C++ 多个数域的置换,c++,vector,permutation,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 (

我需要从数组中的多个数字范围生成置换

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 1 2 3 4 5

我认为可交换是一组可以交换的范围?所以[[1,3],[4,6]]意味着[1,3](索引1和索引2)中的任何内容都可以在该范围内交换,同样地,对于[4,6],范围也不会重叠吗

typedef向量::常量迭代器SwappableIter;
无效生成项(向量和数据、,
可交换ITER开始,可交换ITER结束)
{
如果(开始==结束){
打印(数据);
}
否则{
vector::iterator start=data.begin()+(*begin)[0],
stop=data.begin()+(*begin)[1];
排序(启动、停止);
做{
generatePermutations(数据,开始+1,结束);
}while(下一次排列(开始,停止));
}
}

这是一个稍微修改过的生成算法版本(已损坏)

int-generatePermutations(vector&myVector,vector&swappable){
做
{
做
{
打印(myVector);
//生成第二段的置换
}while(next_置换(myVector.begin()+可交换[1][0],myVector.begin()+可交换[1][1]);
//重新排序第二段
排序(myVector.begin()+可交换[1][0],myVector.begin()+可交换[1][1]);
//计算第一段的置换
}while(next_置换(myVector.begin()+可交换[0][0],myVector.begin()+可交换[0][1]);
}

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

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

只要把线移开就行了

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

代码应该开始工作。

什么是
swappable
?为什么代码中没有注释?添加了注释。swappable用于保持第一个和最后一个位置,在它们之间我需要生成排列。好的。你有没有试着在调试器中单步检查代码,看看为什么它总是给出相同的结果?我很困惑我不明白你想做什么,我也看不到你提供的例子中的模式。你能详细说明一下吗?我很惊讶它产生了任何东西,你的算法没有意义,你正在调用
pop_back()
swappable
向量上,这意味着在第一次递归调用后,它不包含任何内容,while循环将访问无效项…是的,范围将永远不会重叠。如果
swappable
应该是范围向量,请使用
std::pair
或自定义
struct
而不是嵌套向量。是的,是配对会更好;我在示例中保留了问题的类型。这不能很好地扩展;例如,当可交换时。size()==10。@Fred,呃,这可能是因为您设置的范围不正确,而不是上述函数有任何错误!@Nim:它们是如何设置错误的?这是直接从问题中的设置方式复制的。您是否也注意到编译器警告?@Nim:您怎么知道的[1,3)不正确?它与问题中列出的所需输出匹配。即使接受您称之为“不正确的输入”,您的代码的结果也与您描述的不匹配!您看到输出的第3行和第4行是如何相同的吗?@Fred,正要更新我的注释…)如果您选择[1,3],那么这只会给你两个项目,例如,(1,2),唯一其他可能的组合是(2,1)-上面生成的,范围[4,6](4,5)->(5,4)也是一样的,所以输出只会显示-从这个意义上说,上面是正确的(除非我缺少其他一些组合),我也在打印中间步骤。输出:
0 2 3 5 4
不可能是一个可能的排列…问题中的代码,在删除了你提到的两行之后,不起作用。@Fred Nurk:想解释一下它以什么方式不起作用吗?还是说在执行co时缺少的
\include
语句de添加了所需的
#include
s,并注释掉了我提到的行,我得到的结果与@Radek所列出的结果类似。请参阅。注意上一次警告引起的UB,四个输出行如何有一行重复,以及预期输出中如何缺少一行。(顺便说一句,这不是我的反对票;我没有反对票。)@Fred:这很公平。但很难精确匹配列出的输出(你也没有这样做),因为最后一行的
1
2
取代。
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));
  }
}
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]));
}
swappable.pop_back();
generatePermutations(myVector, swappable);