二维向量中元素的所有排列(笛卡尔积)
Posted
技术标签:
【中文标题】二维向量中元素的所有排列(笛卡尔积)【英文标题】:All Permutations of Elements in a 2D Vector (Cartesian Product) 【发布时间】:2012-06-18 22:00:08 【问题描述】:这是我一直坚持的一小部分,它是一个更大的任务的一部分。
我有一个二维向量,例如:
v1: 0 1 2 3 4
v2: 0 1 2
v3: 0 1 2 3 4
v4: 0 1 2 3
v5: 0 1 2 3 4
(每一行都是一个向量)
我需要找到所有排列,从每一行中选择一个元素。正如有人指出的那样,这将是笛卡尔积。 我尝试使用循环,但这只会在一个方向上起作用(它错过了很多排列) 我还研究了 next_permutation,但我不确定是否可以将其应用于 2D 矢量。
此外,行数不是静态的,所以我不能嵌套 5 个循环,因为根据条件可能会有更多或更少的行。
有没有办法做到这一点?
【问题讨论】:
Perfoming Cartesian product on arrays 的可能重复项 您要寻找的不是子集,而是笛卡尔积(从每个元素中挑选一个元素的所有方法)。 @templatetypedef 啊,我已经更正了标题。谢谢 【参考方案1】:我只写一个可能的答案,效率不是很高,但应该可以使用。
请注意,我假设(在您的示例中)您想要所有 5 元素组,第一个元素取自 v1,第二个元素取自 v2,第三个元素取自 v3,等等。
void gen_all (
vector<vector<int> > & output_perms,
vector<vector<int> > const & input,
vector<int> & cur_perm,
unsigned cur_row = 0
)
if (cur_row >= input.size())
// This is where you have found a new permutation.
// Do whatever you want with it.
output_perms.push_back (cur_perm);
return;
for (unsigned i = 0; i < input[cur_row].size(); ++i)
cur_perm.push_back (input[cur_row][i]);
gen_all (output_perms, input, cur_perm, cur_row + 1);
cur_perm.pop_back ();
像这样调用上面的函数:(假设v
拥有你原来的集合。)
vector<vector<int> > output;
vector<int> temp;
gen_all (output, v, temp);
正如我之前所说,有很多更高效和优雅的方法,上面的代码甚至可能无法编译(我只是在这里写的。)
【讨论】:
这个问题被标记为homework
。这是否意味着我不应该在代码中发布解决方案?!
我实际上确实在这里找到了一个递归笛卡尔积函数,它给了我一个很好的查看位置。不幸的是,事实证明我看待问题的整个方式效率低下,我应该一直使用回溯。不过感谢您的解决方案,它比其他一些尝试更容易理解。【参考方案2】:
std::next_permutation
仅适用于一组迭代器。它不保留任何静态内存,它完全基于迭代器的当前状态。这意味着您一次可以在多个向量上使用它。不要试图一次置换整个结构。
【讨论】:
以上是关于二维向量中元素的所有排列(笛卡尔积)的主要内容,如果未能解决你的问题,请参考以下文章