输出或遍历一组的所有对组合的标准算法?

时间:2014-05-31 09:15:21

标签: c++ algorithm stl

是否有标准算法输出集合的所有对组合(例如std::set),或运行此类对组合的操作并将结果写为另一个集合,如std::transform组合2从N?

目标是我们不需要自己编写双循环或递归。或者在现有库等的帮助下尽可能减少这项工作。

要明确的是,如果我们有一组{1,2,3},那么这对组合将是:

[1,2]
[1,3]
[2,3]

2 个答案:

答案 0 :(得分:2)

我不知道标准方法,但这是一个简单的工作示例,我个人无法想到更有效的方法:

// set up some sample data:
std::set<int> myset;
for (int i=0; i < 5; i++ ) 
{
    myset.insert(i);
}

std::set<int>::iterator it;
std::set<int>::iterator it2;

for( it=myset.begin(); it != myset.end(); ++it) {

    int a = *it;
    it2 = std::set<int>::iterator(it);
    it2++;
    for(; it2 != myset.end(); it2++) {
        int b = *it2;
        std::cout << "[" << a << "," << b << "]";
    }
}

产生输出:

[0,1][0,2][0,3][0,4][1,2][1,3][1,4][2,3][2,4][3,4]

当然你需要创建std :: pair&lt;&gt;将两个元素(或类似的)放入输出集中,而不是将它们吐出到控制台。

希望有所帮助。

答案 1 :(得分:0)

对此没有标准的库算法,但很容易编写自己的STL算法来做你想要的。

#include <functional>
#include <iostream>
#include <set>
#include <vector>

template <typename FwdIt, typename Fn>
void for_each_pair(FwdIt first, FwdIt last, Fn func)
{
    for (; first != last; ++first) {
        for (FwdIt next = first; ++next != last;) {
            func(*first, *next);
        }
    }
}

template <typename FwdIt, typename OutIt>
OutIt copy_pairs(FwdIt first, FwdIt last, OutIt dest)
{
    for (; first != last; ++first) {
        for (FwdIt next = first; ++next != last;) {
            *dest++ = std::make_pair(*first, *next);
        }
    }
    return dest;
}

template <typename FwdIt, typename OutIt, typename BinOp>
OutIt transform_pairs(FwdIt first, FwdIt last, OutIt dest, BinOp op)
{
    for (; first != last; ++first) {
        for (FwdIt next = first; ++next != last;) {
            *dest++ = op(*first, *next);
        }
    }
    return dest;
}

int main()
{
    std::set<int> seq{ 1, 2, 3 };

    for_each_pair(
        std::begin(seq), std::end(seq),
        [](int a, int b){ std::cout << '[' << a << ',' << b << "]\n"; }
    );

    std::vector<std::pair<int, int>> vec;
    copy_pairs(std::begin(seq), std::end(seq), std::back_inserter(vec));

    for (auto &pr : vec) {
        std::cout << '[' << pr.first << ',' << pr.second << "]\n";
    }

    std::vector<int> vec2;
    transform_pairs(std::begin(seq), std::end(seq), std::back_inserter(vec2), std::plus<int>());

    for (auto value : vec2) {
        std::cout << value << '\n';
    }
}