Увеличить карту ICL, которая заменяет значения в интервалах?

ICL Boost interval_map имеет два вида поведения: += а также insert, Оба полезны в другом контексте. Первый складывает значения в общих пересечениях двух существующих интервалов. Второе просто вводит новое значение только в ранее не назначенный интервалы (в предварительно назначенных интервалах значение сохраняется).

Однако мне нужно немного отличающееся поведение, например, в приведенном ниже примере вместо получения нежелательной карты интервалов. (1.,2.)->1 , (2.5,3.)->3, (3.,5.)->2 Я получаю вместо желаемого (1.,2.)->1 , (2.5,5.)->3,

То есть, что новые вставленные значения заменяют старые значения? Как мне объявить interval_map чтобы получить это заменяющее поведение?

#include<boost/icl/interval_map.hpp>
int main(){
boost::icl::interval_map<double, int> joined_map;
joined_map.insert( std::make_pair(
boost::icl::interval<double>::open(1., 2.),
1
));
joined_map.insert( std::make_pair(
boost::icl::interval<double>::open(3., 5.),
2
));
joined_map.insert( std::make_pair(
boost::icl::interval<double>::open(2.5, 5.),
3
)); // this line doesn't replace the old value 2, it keeps it.
}

Бонус: это то, что boost::icl::map должен делать? Как мне это использовать?

2

Решение

Вы можете просто стереть содержимое раздела, который вы собираетесь перезаписать перед вставкой:

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

#include <iostream>
#include <boost/icl/interval_map.hpp>

namespace icl = boost::icl;

int main()
{
icl::interval_map<double, int> joined_map;
using ival = icl::interval<double>;

joined_map.add({ival::open(1., 2.), 1});
joined_map.add({ival::open(3., 5.), 2});
std::cout << "#1: "; for(auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";

joined_map.erase(ival::open(3., 6.));
joined_map.add({ival::open(3., 6.), 4});
std::cout << "#2: "; for(auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";
}

Это печатает:

#1: (1,2): 1, (3,5): 2,
#2: (1,2): 1, (3,6): 4,

Который я верю, что вы хотели.


старый текст ответа для комический рельеф будущая ссылка

У меня такое чувство, что семантика interval_map — это не то, что вы ожидаете. Я немного поиграл с этим сейчас и не могу сказать, что понимаю, но знаю достаточно, чтобы это увидеть там не простое отображение 1: 1 вставленных вещей и «элементов», хранящихся в контейнере.

По этой причине возникает много удивительных отклонений от std :: map.

  • нет никаких operator[], но operator[] перегружен (возвращается const)
  • find() возвращает const_iterator (предположительно потому, что он может возвращать «виртуальный узел», который каким-то образом получен из фактических данных). Так что вы не можете просто ожидать map.erase(find(k)) — вы должны явно стереть по ключу или интервалу.
  • имеются add а также subtract методы (кроме insert).

Демо-код:

#include <iostream>
#include <boost/icl/interval_map.hpp>
#include <boost/icl/interval.hpp>

namespace icl = boost::icl;

int main()
{
icl::interval_map<double, int,
icl::partial_absorber,
/*ICL_COMPARE Compare =*/ ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, double),
/*ICL_COMBINE Combine =*/ ICL_COMBINE_INSTANCE(icl::inplace_plus, int),
/*ICL_SECTION Section =*/ ICL_SECTION_INSTANCE(icl::inter_section, int)
> joined_map;
using ival = icl::interval<double>;

joined_map.add({ival::open(1., 2.), 1});
joined_map.add({ival::open(3., 5.), 2});
std::cout << "#1: "; for (auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";
auto clone1 = joined_map;

joined_map.add({3., 2});
std::cout << "#2: "; for (auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";
auto clone2 = joined_map;

joined_map.add({3., 2});
std::cout << "#3: "; for (auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";
auto clone3 = joined_map;

joined_map.add({ival::open(0., 6.), 10});
std::cout << "#4: "; for (auto el : joined_map) std::cout << el.first << ": " << el.second << ", "; std::cout << "\n";
auto clone4 = joined_map;

for (double x = 0; x < 7; x += .5)
{
std::cout << x
<< "\t" << clone1(x)
<< "\t" << clone2(x)
<< "\t" << clone3(x)
<< "\t" << clone4(x)
<< "\n";
}
}

Видеть это Жить на Колиру, печатает:

#1: (1,2): 1, (3,5): 2,
#2: (1,2): 1, [3,5): 2,
#3: (1,2): 1, [3,3]: 4, (3,5): 2,
#4: (0,1]: 10, (1,2): 11, [2,3): 10, [3,3]: 14, (3,5): 12, [5,6): 10,
0   0   0   0   0
0.5 0   0   0   10
1   0   0   0   10
1.5 1   1   1   11
2   0   0   0   10
2.5 0   0   0   10
3   0   2   4   14
3.5 2   2   2   12
4   2   2   2   12
4.5 2   2   2   12
5   0   0   0   10
5.5 0   0   0   10
6   0   0   0   0
6.5 0   0   0   0

Надеюсь это поможет

4

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

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector