Использование объявления структурированной привязки в цикле for на основе диапазона - PullRequest
0 голосов
/ 13 июля 2020

Я пытаюсь объединить два контейнера std::map (скажем, std::map<int, int> foo, bar) в третий std::map (скажем, std::map<int, int> foobar).

Я знаю, что могу добиться этого с помощью итераторов, как показано ниже:

    std::map<int, int>::iterator itr1 = foo.begin();
    std::map<int, int>::iterator itr2 = bar.begin();

    for (; itr1 != foo.end() && itr2 != bar.end(); ++itr1, ++itr2) 
    {
      foobar[itr1->first] += itr1->second;
      foobar[itr2->first] += itr2->second;
    }

Но как я могу использовать Range-based для l oop (и, возможно, в сочетании с объявлением структурированной привязки), чтобы добиться того же?

Или есть лучший способ объединить эти два ассоциативных контейнера?

РЕДАКТИРОВАТЬ: Ожидаемый ответ на этот вопрос должен взять два контейнера (std::map здесь) и объединить их в одну объединенную / объединенную карту с ключами из обоих соответствующих ассоциативных контейнеры и значения добавляемых повторяющихся ключей.

Пример: Если задано std::map контейнеры foo и bar:

  std::map<int, int> foo = {{1, 10}, {2, 20}, {3, 30}};
  std::map<int, int> bar = {{3, 50}, {4, 60}};

Затем ` foobar 'должно быть:

  std::map<int, int> foobar = {{1, 10}, {2, 20}, {3, 80}, {4, 60}};

Все это делается в единственном диапазоне на основе l oop.

Ответы [ 2 ]

4 голосов
/ 13 июля 2020

есть ли лучший способ объединить эти два ассоциативных контейнера?

Самый простой способ - это, вероятно, перебирать их по отдельности:

for(auto[k, v] : foo) foobar[k] += v;
for(auto[k, v] : bar) foobar[k] += v;

Если хотите для удаления любых данных, уже содержащихся в foobar:

foobar = foo;
for(auto[k, v] : bar) foobar[k] += v;
0 голосов
/ 17 июля 2020

Для этого есть стандартный библиотечный алгоритм: std::set_union в <algorithm>. Конечно, это уродливо, потому что в нем используются пары итераторов, но вы, вероятно, можете улучшить это, используя диапазоны.

В любом случае:

std::set_union(
    foo.begin(), foo.end(), 
    bar.begin(), bar.end(),
    std::inserter(foobar, foobar.begin())
);

должно сработать.

PS - Это может быть немного медленно, поскольку std::map сам по себе очень медленный . Я предполагаю, что вы не заботитесь о производительности с этой картой (или она действительно меньше), иначе вам не следует ее использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...