Search code examples
c++algorithmvectorstdmap

Generating vectors of consecutive map element subsets in C++


Question:

How can I create vectors that represent all possible subsets of a specific length containing consecutive elements from a map, according to the natural ordering of the map's keys?

For instance, consider the following map where Sample is a user-defined class:

std::map<int, Sample> myMap = {{15, 'a'}, {21, 'b'}, {33, 'c'}, {37, 'd'}, {49, 'e'}};

I would like to generate vectors of length 3 that contain the values of consecutive keys in the map. The result should look like this:

std::vector<Sample> subset1 = {'a', 'b', 'c'};
std::vector<Sample> subset2 = {'b', 'c', 'd'};
std::vector<Sample> subset3 = {'c', 'd', 'e'};

How can I achieve this in C++?


Solution

  • You may iterate iver the map as key are ordered:

    std::vector<std::array<Sample, 3u>> get_triplets(const std::map<int, Sample>& samples)
    {
        if (samples.size() < 3) {
            return {};
        }
        std::vector<std::array<Sample, 3u>> res;
    
        auto it = samples.begin();
        auto it1 = std::next(it);
        auto it2 = std::next(it1);
    
        for (; it2 != samples.end(); ++it, ++it1, ++it2) {
            res.push_back({{it->second, it1->second, it2->second}});
        }
        return res;
    }
    

    Live Demo

    Edit: to have n-uplets, small changes from previous triplet version:

    std::vector<std::vector<Sample>> get_n_uplets(std::size_t n, const std::map<int, Sample>& samples)
    {
        if (samples.size() < n) {
            return {};
        }
        std::vector<std::vector<Sample>> res;
    
        auto first = samples.begin();
        auto last = std::next(first, n - 1);
    
        for (; last != samples.end(); ++first, ++last) {
            std::vector<Sample> inner;
    
            for (auto it = first; it != std::next(last); ++it) {
                inner.push_back(it->second);
            }
            res.push_back(inner);
        }
        return res;
    }
    

    Live Demo