在 C++ 中产生一组整数的排列。获取分段错误
Posted
技术标签:
【中文标题】在 C++ 中产生一组整数的排列。获取分段错误【英文标题】:Producing permutations of a set of integers in C++. Getting Segmentation Fault 【发布时间】:2014-02-16 20:52:54 【问题描述】:我试图解决一个涉及产生一组数字的所有排列的问题。这个想法似乎很简单(下面的代码),但我不断遇到分段错误。谁能告诉我我做错了什么?
void permute(set<int>& s, vector<int>& v)
if(s.empty())
// read the permutation in v.
return;
set<int>::iterator i;
for(i = s.begin(); i != s.end(); i++)
int x = *i;
s.erase(i);
v.push_back(x);
permute(s, v);
v.pop_back();
s.insert(x);
【问题讨论】:
擦除和插入会弄乱您的迭代器,您不能忽略这一点。检查它们的返回值并相应地更新i
啊,您知道吗,std::set
是排序容器,因此,无论您以什么顺序插入元素,它们最终都会以排序(升序)顺序结束?
另外,正如已经指出的那样,您在使用递归对迭代器做坏事,因为它们在递归期间变得无效。
【参考方案1】:
要在 C++ 中生成所有排列,请使用 std::next_permutation
。这里的问题是您不能置换集合,因为排序是 preset 由关键比较运算符(在您的情况下为小于运算符)。您可以做的是将您的值存储在一个非关联容器中,然后试一试。
#include <set>
#include <algorithm>
#include <iterator>
#include <vector>
using namespace std;
void permut(std::set<int> const &inp, std::vector<int> &all_permutations)
vector<int> tmp(inp.size());
copy(inp.begin(), inp.end(), tmp.begin());
vector<int> all_permutations;
do
copy(tmp.begin(), tmp.end(), back_inserter(all_permutations));
while (std::next_permutation(tmp.begin(), tmp.end()));
【讨论】:
【参考方案2】:permute()
函数在迭代可变容器并进行更改时递归调用自身。这违反了迭代器有效性承诺。
你可以尝试基于 std::next_permutation()
【讨论】:
【参考方案3】:我还没有深入了解您可以从集合中获得的确切行为,但很明显,您在 for 循环中所做的事情足以使迭代器无效。我建议重新设计一些东西,让你有两组,处理一组(开始是满的),同时在另一个(开始是空的)中生成排列。
【讨论】:
抱歉,建议使用排序容器来存储排列似乎不是一个好的答案。 你当然是对的!我没有想到一套通过的含义。以上是关于在 C++ 中产生一组整数的排列。获取分段错误的主要内容,如果未能解决你的问题,请参考以下文章