Как вычесть один список ключей карты из другого и получить новую карту (карта A — mab B = карта C)

#c #boost #stl #map #subtraction

#c #повысить #stl #словарь #вычитание

Вопрос:

Итак, у меня есть 2 std::map s <string, shared_ptr<file> > , один «старый», другой «новый», я хочу получить, какие файлы были удалены, и, таким образом, иметь возможность выполнять итерации по-разному и делать некоторые вещи с shared_ptr. Возможно ли такое и как это сделать?

Комментарии:

1. Взгляните на std::set_difference .

Ответ №1:

Хотя достаточно легко написать это самостоятельно (повторить A и проверить, присутствует ли ключ в B ), это выглядит как работа для std::set_difference . Однако для сравнения ключей нам понадобится лямбда или какой-либо пользовательский предикат:

 #include <iterator>
#include <map>
#include <string>
#include <algorithm>

typedef std::map<std::string, MyPtr> my_map;

my_map A; // given
my_map B; // given

void make_a_difference()
{
  my_map C; // will hold the result

  std::set_difference(A.begin(), A.end(),
                      B.begin(), B.end(),
                      std::insert_iterator<my_map>(C, C.end()),
              [](const my_map::value_type amp; a, const my_map::value_type amp; b)
              { return a.first < b.first; }
                     );
}
  

Если вы хотите написать это самостоятельно, вам следует подумать о том, чтобы воспользоваться тем фактом, что оба диапазона уже отсортированы, так что вы можете добиться большего, чем плоский поиск существования, продвигая два итератора параллельно.

Если у вас нет C 11, просто используйте этот предикат вместо лямбда:

 bool my_comp(const my_map::value_type amp; a, const my_map::value_type amp; b)
{
  return a.first < b.first;
}
  

Остерегайтесь, что нет сравнения по отображенному типу! Таким образом, если у вас один и тот же строковый ключ на обеих картах, то в результате такого элемента не будет, даже если два сопоставленных значения отличаются. Если это нежелательно, вам нужен другой выходной контейнер (например, a std::multimap<my_map::key_type, my_map::mapped_type> ) и другой предикат.