从向量生成元组(通用算法)

时间:2013-01-26 22:06:51

标签: c++ stl

想象一下,我们有一个只有唯一值的向量,并希望生成所有对。这样做的算法是:

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。

谢谢!

1 个答案:

答案 0 :(得分:2)

您所描述的被称为 k-combinations ,这是组合学领域中非常重要的概念。来自一组 n 元素的 k 元素的唯一组合数由公式 n表示! /(K!(N-K)!)

要以通用方式有效地解决这个问题,您应该研究std::tuple和可变参数模板(C ++ 11特性)。但是,如果您在编译时不知道维度,则必须创建一个递归函数,该函数有两个参数:所有项的列表和 k ,可从中选择的数字项名单。

然后,对于集合中的每个元素 e ,创建一个包含该元素的列表以及以 k-1 递归调用该函数的结果作为要选择的数字仅提供列表中 e 之后的列表元素。这将阻止在递归的多个子树中创建相同的子集。

希望对你来说足够清楚。 :)如果您还有其他问题,请随时提出更多解释。