Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Boost`interval\u map`-如何定制触控聚合_C++_Boost Icl - Fatal编程技术网

C++ Boost`interval\u map`-如何定制触控聚合

C++ 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

Boost ICL
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
函数。ICL
interval_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)}