想象一下,我们有一个只有唯一值的向量,并希望生成所有对。这样做的算法是:
vector< int > data;
// ... pushback some data
vector< vector< int > > pairs;
for( size_t i = 0; i < data.size() - 1; ++i )
{
for( size_t j = i + 1; j < data.size(); ++j )
{
vector< int > pair;
pair.push_back( data[i] );
pair.push_back( data[j] );
pairs.push_back( pair );
}
}
现在,对于三元组,算法将更改为:
vector< int > data;
// ... pushback some data
vector< vector< int > > triples;
for( size_t i = 0; i < data.size() - 2; ++i )
{
for( size_t j = i + 1; j < data.size() - 1; ++j )
{
for( size_t k = j + 1; k < data.size(); ++k )
{
vector< int > triple;
triple.push_back( data[i] );
triple.push_back( data[j] );
triple.push_back( data[k] );
triples.push_back( triple );
}
}
}
很容易想出四元组和其他元组类型的代码。
有人可以告诉我如何实现一般算法来生成所有类型的元组吗?既然我们在它,它如何计算向量中元素数量的元组数?对于对,公式为n(n-1)/ 2。
谢谢!
答案 0 :(得分:2)
您所描述的被称为 k-combinations ,这是组合学领域中非常重要的概念。来自一组 n 元素的 k 元素的唯一组合数由公式 n表示! /(K!(N-K)!)
要以通用方式有效地解决这个问题,您应该研究std::tuple
和可变参数模板(C ++ 11特性)。但是,如果您在编译时不知道维度,则必须创建一个递归函数,该函数有两个参数:所有项的列表和 k ,可从中选择的数字项名单。
然后,对于集合中的每个元素 e ,创建一个包含该元素的列表以及以 k-1 递归调用该函数的结果作为要选择的数字仅提供列表中 e 之后的列表元素。这将阻止在递归的多个子树中创建相同的子集。
希望对你来说足够清楚。 :)如果您还有其他问题,请随时提出更多解释。