boost::icl::interval_map重叠并集
boost::icl::interval_map union on overlap
是否可以使interval_map具有以下累积行为:
[1..3]->1 +
[2..4]->2 +
[5..7]->3 +
[6..8]->4
=
[1..4]->{1,2}, [5..8]->{3,4}
+
[3..6]->42
=
[1..8]->{1,2,3,4,42}
我想我以前也遇到过类似的问题,找不到支持库的方法。
PS。发现post-boost::multi_index_container,在容器内对std::set进行操作
比较起来很有趣,因为它基本上是在查询时进行类似的间隔合并。这有好处(它保留了插入历史记录,因此您可以查询其他受益于无损耗存储的结果)。它还以插入效率换取更多的查询成本。
我可能会自己编写插入/组合操作。
我试着在这里想出一个描述性的名字。由于操作感觉类似于将"水滴"降落到更大的"水池"中,我将操作称为mix
:
template <typename Map, typename V = typename Map::segment_type>
void mix(Map& m, std::initializer_list<V> drops) {
typename Map::codomain_combine combine;
for (auto drop : drops) {
// combine with all overlapping existing segments
auto range = m.equal_range(drop.first);
for (auto it = range.first; it != range.second; ++it) {
combine(drop.second, it->second);
drop.first = hull(drop.first, it->first);
}
m.set(drop); // logically equivalent to m.add(drop) here
}
}
有了这个,你可以清楚地表达你想要的行为,比如:
int main() {
using Map = boost::icl::interval_map<int, Ints>;
using Interval = Map::interval_type::type;
Map m;
std::cout << m << "n";
mix(m, { {Interval::closed(1,3), {1}},
{Interval::closed(2,4), {2}},
{Interval::closed(5,7), {3}},
{Interval::closed(6,8), {4}} });
std::cout << m << "n";
mix(m, { {Interval::closed(3,6), {42}} });
std::cout << m << "n";
}
输出将是
{}
{([1,4]->{1,2,})([5,8]->{3,4,})}
{([1,8]->{1,2,3,4,42,})}
完整演示
在Coliru上直播
#include <boost/icl/interval_map.hpp>
#include <set>
#include <iostream>
template <typename Map, typename V = typename Map::segment_type>
void mix(Map& m, std::initializer_list<V> drops) {
typename Map::codomain_combine combine;
for (auto drop : drops) {
// combine with all overlapping existing segments
auto range = m.equal_range(drop.first);
for (auto it = range.first; it != range.second; ++it) {
combine(drop.second, it->second);
drop.first = hull(drop.first, it->first);
}
m.set(drop); // logically equivalent to m.add(drop) here
}
}
// For debug: an ostreamable std::set<int>
struct Ints : std::set<int> {
using std::set<int>::set;
friend std::ostream& operator<<(std::ostream& os, Ints const& s) {
os << '{';
for(auto i : s) os << i << ",";
return os << '}';
}
};
int main() {
using Map = boost::icl::interval_map<int, Ints>;
using Interval = Map::interval_type::type;
Map m;
std::cout << m << "n";
mix(m, { {Interval::closed(1,3), {1}},
{Interval::closed(2,4), {2}},
{Interval::closed(5,7), {3}},
{Interval::closed(6,8), {4}} });
std::cout << m << "n";
mix(m, { {Interval::closed(3,6), {42}} });
std::cout << m << "n";
}
相关文章:
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- Ardunio UNO解决了多个重叠的定时器循环
- 使用一个考虑到std::map中键值的滚动或换行的键
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 允许从 std::map 的密钥窃取资源?
- 算术序列与区间的最大重叠
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将重物插入std::map
- 使用通用值初始化 std::map,不重复
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- C++:当所有条目都保证是唯一时,替代 std::map
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- 使用字符数组作为 Map 中的键
- 按顺序声明的字符数组重叠
- C++如何创建 std::map
- C++ equivalent to Java Map getOrDefault?
- 拆分重叠段