C++ Boost`interval\u map`-如何定制触控聚合
Boost ICLC++ Boost`interval\u map`-如何定制触控聚合,c++,boost-icl,C++,Boost Icl,Boost ICLinterval\u集合可以加入右开区间,在将它们添加到集合中的过程中,这些区间相互接触。例如,区间[0,4)和[4,8)将合并为区间[0,8) 对于间隔\u映射,这更为复杂-间隔相互接触且具有不同的关联值,不会合并: #include <iostream> #include <utility> #include <boost/icl/interval_map.hpp> namespace icl = boost::icl; using
interval\u集合
可以加入右开区间,在将它们添加到集合中的过程中,这些区间相互接触。例如,区间[0,4)
和[4,8)
将合并为区间[0,8)
对于间隔\u映射
,这更为复杂-间隔相互接触且具有不同的关联值,不会合并:
#include <iostream>
#include <utility>
#include <boost/icl/interval_map.hpp>
namespace icl = boost::icl;
using IMap = icl::interval_map<int, int>;
int main()
{
IMap m;
m += std::make_pair(IMap::interval_type::right_open(0, 4), 1);
m += std::make_pair(IMap::interval_type::right_open(4, 8), 2);
std::cout << m << std::endl;
}
我知道如何自定义重叠聚合的过程,但是我需要自定义另一种情况-触摸聚合。例如,如果间隔彼此接触,并且左间隔的值等于右间隔的值减去1,则必须连接间隔,并且esulting interval必须有一个left interval的值。因此,上面的程序应该打印:
{([0,8)->1)}
使用当前可用的Boost ICL是否可以做到这一点
我可以用间隔映射
进行奇怪的操作,但我认为这会很麻烦,效率低下。我更愿意被指向正确的方向,使用当前可用的ICL自定义项、functor等
这对于间隔映射更为复杂-间隔彼此接触并具有不同的关联值,不会合并:
没有区别,真的
我知道如何定制重叠聚合的过程,但是我需要定制另一个案例——触摸聚合
你似乎在暗示
m += std::make_pair(IMap::interval_type::right_open(4, 8), 2);
将插入[4,8)->2
事实并非如此。这是一个密码域组合操作,结果取决于map的先前状态
当然,你可以这样写:
m.set({Ival::right_open(4, 8), 2});
如果需要,您可以查询前面的插槽,因此您的操作可能如下所示:
// returns true if joined with preceding slot
bool fill_slot(IMap& m, int from, int till, int value) {
bool joined = false;
auto slot = Ival::right_open(from, till);
if (within(slot, m)) {
// There is overlap, I don't know how you want to handle this.
// You can add some logic here.
} else {
auto preceding = m(from - 1);
if (preceding && value == preceding + 1) {
joined = true;
value = preceding;
}
}
m.set({slot, value});
return joined;
}
现在您可以编写如下测试用例:
int main() {
{
IMap m;
fill_slot(m, 0, 4, 1);
fill_slot(m, 4, 8, 2);
std::cout << m << std::endl;
}
{
IMap m;
fill_slot(m, 0, 4, 1);
fill_slot(m, 4, 8, 3);
std::cout << m << std::endl;
}
{
IMap m;
fill_slot(m, 0, 4, 1);
fill_slot(m, 5, 8, 2);
std::cout << m << std::endl;
}
}
抱歉地说-我一直试图避免问这个问题的是您的
fill_slot
函数。ICLinterval_map
有八个模板参数-我希望可以使用它们以我需要的方式自定义映射。例如,使用非默认的functor,或者编写我自己的functor。或者-自定义interval
类型本身…希望并没有多大帮助。请参阅“自定义”地图以执行其他操作只会使行为未定义。如果您了解您的特殊用途语义在哪些方面可以符合这些规则,那么就去做吧。但就目前而言,我认为它不能(很多细节没有描述).从我坐的地方看,你似乎有两样东西:一方面是一个合适的学习项目,另一方面是一个合适的学习项目(Boost ICL)。我认为这太棒了。该库肯定是最被低估的Boost库之一。我只是不确定它是否有固定的解决方案。我也不确定你为什么想要它(如果你超出了图书馆的指定用途,并假设图书馆将促进is,那么你不会失去使其具有吸引力的所有复杂性保证吗?)ICL看起来像是适应性很强的图书馆,包括它的“重叠聚合”概念。为什么没有“接触聚合”功能性?我希望更深入地参与ICL的人能帮助我找到隐藏它的方法
int main() {
{
IMap m;
fill_slot(m, 0, 4, 1);
fill_slot(m, 4, 8, 2);
std::cout << m << std::endl;
}
{
IMap m;
fill_slot(m, 0, 4, 1);
fill_slot(m, 4, 8, 3);
std::cout << m << std::endl;
}
{
IMap m;
fill_slot(m, 0, 4, 1);
fill_slot(m, 5, 8, 2);
std::cout << m << std::endl;
}
}
{([0,8)->1)}
{([0,4)->1)([4,8)->3)}
{([0,4)->1)([5,8)->2)}