我有一个离散的空间(比如整数)。他们分组分组说:
group A: 1, 4, 6
group B: 2, 3, 5
etc
如果组中的项目是有序的,并且组之间没有重复的数字。
我有一个处理程序,可以为新项目汇集每个组,其中可能有零个或多个新项目。
说:
pool Group A - returns 1, 4
pool Group B - returns 2, 3
pool Group A - returns 6
pool Group B - returns 5
将新项目添加到组并汇集它们的过程是连续的。
我需要能够在任何时候告诉已经处理的离散空间中有一个洞。
在这个例子中,当我处理1时 - 结果是没有 - 没有洞。然后,一旦我处理4,这将创建一个介于1和4之间的洞。然后添加2,仍然有洞,但是当我添加3时,就没有洞了。
我正在考虑使用boost :: interval,我只是在它出现时添加每个项目。似乎非常容易实现,但增强间隔针对间隔进行了优化。我不喜欢使用std :: vector或boost :: dynamic_bitset,因为我没有理由不断增加跟踪的内存占用。我不需要处理哪些数字 - 我只需要知道是否有漏洞。
性能要求很高。我很好奇有没有更好的方法来做到这一点。有什么想法吗?
答案 0 :(得分:1)
你可以确实使用Boost ICL。
默认间隔组合样式是“加入”。这正是您所需要的!所以,它是本垒打。
这是一个简单的演示,其中包含示例中给出的输入事件。我在每个事件中打印记录的状态(对于Boost ICL IO支持而言!)。
<强> Live On Coliru 强>
#include <boost/icl/interval_set.hpp>
#include <iostream>
using Set = boost::icl::interval_set<int>;
using Interval = Set::interval_type;
int main() {
Set record;
// pool Group A - returns 1, 4
// pool Group B - returns 2, 3
// pool Group A - returns 6
// pool Group B - returns 5
int stepcount = 0;
for (int sample : {
1, 4,
2, 3,
6,
5 })
{
record.insert(sample);
std::cout << "state at #" << ++stepcount << ": " << record << "\n";
}
}
打印哪些:
state at #1: {[1,1]}
state at #2: {[1,1][4,4]}
state at #3: {[1,2][4,4]}
state at #4: {[1,4]}
state at #5: {[1,4][6,6]}
state at #6: {[1,6]}
正如你所看到的,当3关闭它时,差距确实消失了。这似乎正是你想要/描述的。
注意您会很高兴知道如果漏洞很少/很大(连续范围是“漏洞”),那么ICL甚至可以获得高度压缩的存储表示。这是图书馆功能的核心。所以,描述事情,我想你会没事的。
如果您需要更好的可扩展性,您可以选择截断数字上升时不再需要的“历史记录”。你做了
record.erase(Interval::open(0, 4));
std::cout << "state after erase: " << record << "\n";
哪个会打印
state after erase: {[4,6]}