C++; 我想建立一个C++程序,它根据n个因子所取的元素的数量来显示所有可能的组合。
让我们假设一个向量vec[6],上面有元素123456。C++; 我想建立一个C++程序,它根据n个因子所取的元素的数量来显示所有可能的组合。,c++,combinations,combinatorics,C++,Combinations,Combinatorics,让我们假设一个向量vec[6],上面有元素123456。 使用组合公式,6!/4.(6 - 4)! = 15种可能性 我想生成一个函数,给出所有15种可能性的结果,4乘4,不重复,例如: 1234 1235 1236 2 3 4 5 等等 我现在正在使用这段代码,但我想使用向量(v[6])中的数字 #包括 #包括 #包括 空梳(整数N,整数K) { std::字符串位掩码(K,1);//K前导1 bitmask.resize(N,0);//N-K尾部0 //打印整数和置换位掩码 做{ 对于(in
使用组合公式,6!/4.(6 - 4)! = 15种可能性
我想生成一个函数,给出所有15种可能性的结果,4乘4,不重复,例如:
1234
1235
1236
2 3 4 5
等等 我现在正在使用这段代码,但我想使用向量(v[6])中的数字
#包括
#包括
#包括
空梳(整数N,整数K)
{
std::字符串位掩码(K,1);//K前导1
bitmask.resize(N,0);//N-K尾部0
//打印整数和置换位掩码
做{
对于(int i=0;i cout从子集S={1,2,3,…,k}开始,这是第一个子集。通过检查右边的元素(从最后一个子集开始)生成下一个子集,如果可以,则增加它(如果它
{1,2,3}、{1,2,4}、{1,2,5}、{1,3,4}、{1,3,5}、{1,4,5}、{2,3,4}、{2,3,5}、{2,4,5}、{3,4,5}、{3,4,5}
#include <iostream>
#include <vector>
std::ostream& operator<<(std::ostream& o, std::vector<int>& a)
{
o << "{";
for (std::vector<int>::const_iterator it = a.begin(); it != a.end(); ++it) {
o << *it;
if (it + 1 < a.end()) o << ",";
}
return o << "}";
}
int main()
{
const int N = 7;
const int k = 4;
std::vector<int> A(k);
// initialize
for (int i = 0; i < k; ++i) {
A[i] = i + 1;
}
std::cout << A << std::endl;
int h = 0;
bool done = false;
do {
++A[k-h-1];
for (int t = k - h; t < k; ++t) {
A[t] = A[t-1] + 1;
}
if (A[k-h-1] < N - h) {
// last element can be incremented, stay there...
h = 0;
} else {
// last element at max, look back ...
++h;
}
done = (A[0] == N - k + 1);
std::cout << A << std::endl;
} while (!done);
}
#包括
#包括
std::ostream&operator这里有一个C++14解决方案,它使用a来完成这项工作:
#include "combinations"
#include <iomanip>
#include <iostream>
#include <vector>
int
main()
{
std::vector<int> v{1, 2, 3, 4, 5, 6};
int state = 0;
for_each_combination(v.begin(), v.begin() + 4, v.end(),
[&state](auto first, auto last)
{
std::cout << std::setw(2) << ++state << " : ";
while (true)
{
std::cout << *first;
if (++first == last)
break;
std::cout << ' ';
}
std::cout << '\n';
return false;
});
}
可以从上述链接复制/粘贴库的源代码,并检查其工作方式。与使用std::prev_permutation
的解决方案相比,该库的性能非常高。该函数的实现相对简单,但库还包含越来越多的功能易于实现(但同样易于使用):
模板
作用
对于每个组合(投标人优先,
比迪里特中部,
比迪里特最后,
功能f);
模板
作用
对于每种排列(首先是投标人,
比迪里特中部,
比迪里特最后,
功能f);
模板
作用
对于每个可逆排列(BidirIter first,
比迪里特中部,
比迪里特最后,
功能f);
模板
作用
对于每个循环排列(BidirIter first,
比迪里特中部,
比迪里特最后,
功能f);
模板
作用
对于每个可逆循环置换(BidirIter first,
比迪里特中部,
比迪里特最后,
功能f);
图书馆有几个令人愉快的特点,包括:
- 您的输入序列(
vector
或其他)不需要排序
- 通过返回
true
,您可以随时过早地跳出循环
- 如果您没有提前中断循环,序列将始终返回到其原始状态
- 函子始终接收序列的第一个
k
元素的迭代器,因此,如果您告诉函子序列的总长度,也可以对未选择的元素进行操作
可以按原样使用该库,也可以研究并从其实现中获取所需内容。上面的链接包含类似教程的说明,以及每个函数的详细说明。非常简单的递归实现:
struct Combs
{
vector<int> scombs;
template <typename F>
void call_combs(int n, int k, F f)
{
if (k == 0) {
f();
}
else {
scombs.push_back(n - 1);
call_combs(n - 1, k - 1, f);
scombs.resize(scombs.size() - 1);
if (k < n) {
call_combs(n - 1, k, f);
}
}
}
};
...
Combs combs;
const auto& coco = combs.scombs;
combs.call_combs(6, 4, [&coco](){
copy(coco.cbegin(), coco.cend(), ostream_iterator<int>(cout));
cout << endl;
});
struct-Combs
{
向量范围;
模板
无效呼叫梳(整数n、整数k、整数F)
{
如果(k==0){
f();
}
否则{
头骨向后推(n-1);
呼叫梳(n-1,k-1,f);
调整scombs.resize(scombs.size()-1);
if(k cout Replacestd::cout我的意图是让一个函数传递一个数字向量,而不是一个数字,就像这样:void order(intd[],intk){}这是为标准化而提出的,还是在你的待办事项清单上的某个地方?还没有为标准化而提出。它是在大约5年前提交给LWG的。我不确定它是否通过了“广泛需要”的测试我也不确定如何指定它,使其快速。这些函数如果不是比下一个置换等快几个数量级,也是无用的。
#include "combinations"
#include <iomanip>
#include <iostream>
#include <vector>
int
main()
{
std::vector<int> v{1, 2, 3, 4, 5, 6};
int state = 0;
for_each_combination(v.begin(), v.begin() + 4, v.end(),
[&state](auto first, auto last)
{
std::cout << std::setw(2) << ++state << " : ";
while (true)
{
std::cout << *first;
if (++first == last)
break;
std::cout << ' ';
}
std::cout << '\n';
return false;
});
}
1 : 1 2 3 4
2 : 1 2 3 5
3 : 1 2 3 6
4 : 1 2 4 5
5 : 1 2 4 6
6 : 1 2 5 6
7 : 1 3 4 5
8 : 1 3 4 6
9 : 1 3 5 6
10 : 1 4 5 6
11 : 2 3 4 5
12 : 2 3 4 6
13 : 2 3 5 6
14 : 2 4 5 6
15 : 3 4 5 6
template <class BidirIter, class Function>
Function
for_each_combination(BidirIter first,
BidirIter mid,
BidirIter last,
Function f);
template <class BidirIter, class Function>
Function
for_each_permutation(BidirIter first,
BidirIter mid,
BidirIter last,
Function f);
template <class BidirIter, class Function>
Function
for_each_reversible_permutation(BidirIter first,
BidirIter mid,
BidirIter last,
Function f);
template <class BidirIter, class Function>
Function
for_each_circular_permutation(BidirIter first,
BidirIter mid,
BidirIter last,
Function f);
template <class BidirIter, class Function>
Function
for_each_reversible_circular_permutation(BidirIter first,
BidirIter mid,
BidirIter last,
Function f);
struct Combs
{
vector<int> scombs;
template <typename F>
void call_combs(int n, int k, F f)
{
if (k == 0) {
f();
}
else {
scombs.push_back(n - 1);
call_combs(n - 1, k - 1, f);
scombs.resize(scombs.size() - 1);
if (k < n) {
call_combs(n - 1, k, f);
}
}
}
};
...
Combs combs;
const auto& coco = combs.scombs;
combs.call_combs(6, 4, [&coco](){
copy(coco.cbegin(), coco.cend(), ostream_iterator<int>(cout));
cout << endl;
});