简体   繁体   English

C ++递归生成集合的排列

[英]C++ Generate Permutations of a set recursively

I've been assigned the task of writing a C++ function that returns all possible permutations from a group of integers. 我被分配编写一个C ++函数的任务,该函数从一组整数返回所有可能的排列。 I've done a bit of research but all algorithms I find show the permutation being printed out. 我做了一些研究,但是我发现的所有算法都显示出了排列。

The problem I'm running in to is I don't know how to set up the function, specifically, how I should handle receiving data from recursive calls. 我遇到的问题是我不知道如何设置函数,特别是我应该如何处理从递归调用中接收数据。 My first guess was to use a linked list, but I know if I try to return a pointer to a Node I'll end up with a pointer to invalid memory. 我的第一个猜测是使用链表,但是我知道如果尝试返回一个指向Node的指针,最终将得到一个指向无效内存的指针。

My other guess was to use some sort of global linked list of vectors, but I can't imagine how I could add to the linked list from a function itself. 我的另一个猜测是使用某种矢量的全局链接列表,但是我无法想象如何从函数本身添加到链接列表。 Further, this is more sidestepping the problem than actually solving it, and I'd like to actually solve it if at all possible. 此外,这比实际解决问题更能避免问题,并且我想尽可能解决实际问题。

As this is a homework problem, I don't expect anyone to hand me an answer outright. 由于这是一个家庭作业问题,所以我不希望有人直接向我提供答案。 I'm just lost and would greatly appreciate someone pointing me in the right direction. 我只是迷路了,不胜感激有人将我指向正确的方向。

You could use std::next_permutation . 您可以使用std::next_permutation It operates on the data structure so you can do anything you want with the data structure after each iteration. 它在数据结构上运行,因此您可以在每次迭代后对数据结构执行任何所需的操作。

If you're implementing your own permutation logic, suppose you're operating on vector<int>& data , you could add a parameter like vector<vector<int> >& result in your recursive function. 如果要实现自己的置换逻辑,假设您正在对vector<int>& data ,则可以在递归函数中添加一个类似于vector<vector<int> >& result的参数。 Each time a permutation is generated you could simply do result.push_back(data) . 每次生成排列时,您都可以简单地执行result.push_back(data)

One possible approach: store the set in an array, then call a function giving it an array (a ptr to the first item) and the array length as parameters. 一种可能的方法是:将集合存储在数组中,然后调用一个函数,为它提供一个数组(第一个项目的ptr),并将数组长度作为参数。 Make sure the array is initially sorted, say in ascending order, then reorder it to a 'lexically next' permutation on each call. 确保该数组最初是按升序排序的,然后在每次调用时将其重新排序为“词法上的下一个”排列。

You can use next_permutation and accumulate copies of all the permutations: 您可以使用next_permutation并累积所有排列的副本:

template<class T>
vector<vector<T>> permutations(vector<T> input) {
  vector<vector<T>> result{input};
  while (next_permutation(begin(input), end(input)))
    result.push_back(input);
  return result;
}

Since this is a homework problem, I expect you have to generate the permutations yourself. 由于这是一个作业问题,我希望您必须自己生成排列。 But this points to an approach—have an accumulator of type vector<vector<T>> , and pass it as a reference parameter to the recursive version of your algorithm: 但这指向一种方法-拥有类型为vector<vector<T>>的累加器,并将其作为参考参数传递给算法的递归版本:

template<class T>
vector<vector<T>> permutations(const vector<T>& input) {
  vector<vector<T>> output;
  collect_permutations(input, output);
  return output;
}

template<class T>
void collect_permutations(const vector<T>& input, vector<vector<T>>& output) {
  // Instead of printing, simply write to output using push_back() etc.
}

If you in fact want just the combinations (order of the items in the returned set doesn't matter), then I would use the binary counter approach - for a source set of N items, define an N-bit binary counter and count from 0 to 2^N-1 - each bit in the counter corresponds to one of the N items, and each number represents a combination where only the items that have a 1 bit are present in the combination. 如果实际上您只需要组合(返回集中的项目顺序无关紧要),那么我将使用二进制计数器方法-对于N个项目的源集,定义一个N位二进制计数器,并从0到2 ^ N-1-计数器中的每个位对应于N个项目之一,并且每个数字表示一个组合,其中组合中仅包含具有1位的项目。

For permutations, you would then have to generate all possible orderings of the items in each individual combination, along with some way to eliminate duplicates if necessary. 对于排列,您将必须在每个单独的组合中生成所有可能的项目排序,并在必要时通过某种方式消除重复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM