C++一个向量的所有组合
C++ All combinations of a vector
假设我们有一些来自0 to n
的数字,我们希望对大小为s
的数字进行加扰,并希望看到所有可能的组合。
因此,排列的数量恰好等于s! * n!/(s!*(n-s)!)
。
n = 3
和s = 3
的示例:
0 1 2 | 0 1 3 | 0 2 1 | 0 2 3 | 0 3 1 | 0 3 2 | 1 0 2 | 1 0 3 | 1 3 2
1 2 3 | 1 2 0 | 1 3 0 | 2 0 1 | 2 1 0 | 2 0 3 | 2 3 0 | 2 3 1 | 2 1 3
3 0 1 | 3 1 0 | 3 0 2 | 3 2 0 | 3 1 2 | 3 2 1
使用boost/stl有没有一种平滑的方法来实现这一点?
以下是使用T.C.在注释中引用的链接的代码(http://howardhinnant.github.io/combinations.html):
#include "../combinations/combinations"
#include <iostream>
#include <vector>
int
main()
{
std::vector<int> v{0, 1, 2, 3};
typedef std::vector<int>::iterator Iter;
for_each_permutation(v.begin(), v.begin()+3, v.end(),
[](Iter f, Iter l)
{
for (; f != l; ++f)
std::cout << *f << ' ';
std::cout << "| ";
return false;
}
);
std::cout << 'n';
}
0 1 2 | 0 2 1 | 1 0 2 | 1 2 0 | 2 0 1 | 2 1 0 | 0 1 3 | 0 3 1 | 1 0 3 | 1 3 0 | 3 0 1 | 3 1 0 | 0 2 3 | 0 3 2 | 2 0 3 | 2 3 0 | 3 0 2 | 3 2 0 | 1 2 3 | 1 3 2 | 2 1 3 | 2 3 1 | 3 1 2 | 3 2 1 |
与std::next_permutation
相比,该库的一个显著优点是,被排列的元素不需要排序,甚至不需要小于可比元素。例如:
#include "../combinations/combinations"
#include <iostream>
#include <vector>
enum class color
{
red,
green,
blue,
cyan
};
std::ostream&
operator<< (std::ostream& os, color c)
{
switch (c)
{
case color::red:
os << "red";
break;
case color::green:
os << "green";
break;
case color::blue:
os << "blue";
break;
case color::cyan:
os << "cyan";
break;
}
return os;
}
int
main()
{
std::vector<color> v{color::blue, color::red, color::cyan, color::green};
typedef std::vector<color>::iterator Iter;
for_each_permutation(v.begin(), v.begin()+3, v.end(),
[](Iter f, Iter l)
{
for (; f != l; ++f)
std::cout << *f << ' ';
std::cout << "| ";
return false;
}
);
std::cout << 'n';
}
蓝-红-青|蓝-青-红|红-蓝-青|红-青-蓝|青蓝-红|青-红-蓝|蓝-红-绿|蓝-绿-红|红-蓝绿|红-绿-蓝|绿-蓝-红|绿-红-蓝|蓝-青绿色|蓝绿色青色|青蓝色绿色|青绿色蓝色|绿色蓝-青|绿-青-蓝|红-青-绿|红-绿-青|青红-绿|青-绿-红|绿-红-青|绿-青-红|
现场演示
#include <algorithm>
#include <vector>
#include <iterator>
#include <iostream>
void dfs(int depth, int s, int i, std::vector<int>& c, const std::vector<int>& v)
{
if (depth == s)
{
do
{
std::copy(c.begin(), c.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "| ";
}
while (std::next_permutation(c.begin(), c.end()));
}
else
{
for (int j = i + 1; j < (int)v.size(); ++j)
{
c.push_back(v[j]);
dfs(depth + 1, s, j, c, v);
c.pop_back();
}
}
}
int main()
{
std::vector<int> v{ 0, 1, 2, 3 };
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());
std::vector<int> c;
const int length = 3;
dfs(0, length, -1, c, v);
}
输出:
0 1 2 | 0 2 1 | 1 0 2 | 1 2 0 | 2 0 1 | 2 1 0 | 0 1 3 | 0 3 1 | 1 0 3 |
1 3 0 | 3 0 1 | 3 1 0 | 0 2 3 | 0 3 2 | 2 0 3 | 2 3 0 | 3 0 2 | 3 2 0 |
1 2 3 | 1 3 2 | 2 1 3 | 2 3 1 | 3 1 2 | 3 2 1
相关文章:
- 检查向量是否具有所有可能的字符组合
- 从向量的向量中删除向量的组合
- 如何得到几个子向量的组合
- 如何组合两个整数向量
- 如果我们从每个 Y 向量中选择一个值,则 X 数字的每个组合都可能
- 在不使用递归的情况下求解所有 2D 字符串向量组合?(C++)
- 字符串向量的有效组合
- 向量的高效组合最小值和平均值计算
- 如何在 Boost.Sprit.Qi 中从向量制作组合的 ascii::string 规则<string>?
- 将多个向量(函数结果)组合到一个使用模板中
- 双重释放或损坏(输出):使用向量的组合算法0x0000000001a880a0***
- 如何沿行组合两个向量?
- 创建多个向量的所有可能组合
- 如何在 c++ 中将集合和数组合并到向量中
- 在C++编程语言中,如何用n个向量长度的所有可能的字符串组合来填充向量
- 在 C++11 中计算字母和单词的双字母组合的 std::线程向量的问题
- 找到两个向量数组的组合,该数组的总和是 c++ 中所有其他组合的最大值
- 如何在C++中组合向量的元素
- c++组合向量(如果它们共享一个数字)
- 这是用组合向量类重载[]的正确方法吗?