在 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++ 中产生一组整数的排列。获取分段错误的主要内容,如果未能解决你的问题,请参考以下文章

没有指针的 C++ 分段错误 (HackerRank)

C ++分段故障向量[关闭]

C++ 的核心转储分段错误

GDB C++ 出错时无法获取源核心行(分段错误)

在命名管道中获取分段错误(核心转储)错误

c++ 。我试图通过在开关内使用数组来获取用户输入,但是当我运行代码时它显示分段错误?