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++?
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;
}
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;
}