Объединить два форсированных набора в C ++?

У меня есть два мощных интрузивных набора, которые мне нужно объединить. я имею map_old.m_old_attributes увеличить интрузивный набор, который мне нужно объединить m_map_new_attributes повысить интрузивный набор

void DataTest::merge_set(DataMap& map_old)
{

// merge map_old.m_old_attributes set into m_map_new_attributes
}

Каков наилучший способ сделать это? Я не могу найти функцию, которая может сделать слияние для меня? Недавно я начал работать с бустер-навязчивыми наборами, и я не могу найти предопределенные методы, которые могут выполнить слияние, или, может быть, я ошибаюсь?

1

Решение

Действительно, навязчивые наборы — это другой зверь. Они не управляют распределением своих элементов.

Поэтому при слиянии нужно решить, что это средства. Я бы сказал, что разумной интерпретацией было бы то, что вы хотите переехать элементы, содержащиеся внутри map_old Контейнер в DataMap.

Это бы уйти map_old пустой. Вот такой алгоритм:

template <typename Set>
void merge_into(Set& s, Set& into) {
std::vector<std::reference_wrapper<Element> > tmp(s.begin(), s.end());
s.clear(); // important! unlinks the existing hooks
into.insert(tmp.begin(), tmp.end());
}

Обновить С другой стороны, вы можете сделать это с O (1) сложностью памяти, используя немного более хитрый цикл iterater-erase-loop (остерегайтесь повторяющихся мутирующих контейнеров): Жить на Колиру также

    for (auto it = s.begin(); it != s.end();) {
auto& e = *it;
it = s.erase(it);
into.insert(e);
}

Видеть это Жить на Колиру

#include <boost/intrusive/set.hpp>
#include <boost/intrusive/set_hook.hpp>
#include <string>
#include <vector>
#include <functional>
#include <iostream>

namespace bive = boost::intrusive;

struct Element : bive::set_base_hook<> {
std::string data;

Element(std::string const& data = "") : data(data) {}

bool operator< (Element const& rhs) const  { return data < rhs.data; }
bool operator==(Element const& rhs) const  { return data ==rhs.data; }
};

using Set = bive::set<Element>;

template <typename Set>
void merge_into(Set& s, Set& into) {
std::vector<std::reference_wrapper<Element> > tmp(s.begin(), s.end());
s.clear(); // important! unlinks the existing hooks
into.insert(tmp.begin(), tmp.end());
}

int main() {
std::vector<Element> va {{"one"},{"two"},{"three"},{"four"},{"five"},{"six"},{"seven"},{"eight"},{"nine"} };
Set a;
for(auto& v : va) a.insert(v);

std::vector<Element> vb {{"two"},{"four"},{"six"},{"eight"},{"ten"} };
Set b;
for(auto& v : vb) b.insert(v);

assert(9==a.size());
assert(5==b.size());

merge_into(a, b);

assert(a.empty());
assert(10==b.size());
}

Конечно, вы можете придумать другую семантику для операции слияния (которая была бы больше похожа на «копировать» вместо «двигаться»)

1

Другие решения


По вопросам рекламы [email protected]