【发布时间】:2019-12-31 13:24:31
【问题描述】:
我有一个数组或 N 对 (v1, v2) 其中v1 <= v2。这些应该代表从v1 开始到v2 结束的时间事件。它们可以相等,则事件是瞬时的。数组按开始时间排序,v1。
对于给定的范围(L, R),我想找到L <= v1 <= R or L <= v2 <= R 的任何对。这里的想法是让事件在给定范围内开始、发生或结束。
我的主要问题是效率。该数组可能包含数十万个事件。因此,仅对所有对进行线性搜索不是一种选择。
我阅读了一些关于 kd-tree 的信息,但它的问题是它排除了范围的边界并且只会返回 L <= v1 <= R AND L <= v2 <= R。也就是说,只会返回范围内实际发生的事件(开始和结束),而我需要开始或结束(或显然两者)。
我还考虑过保留 2 个查找表(我用双精度表示时间)
std::map<double, Event*> startPoints;
std::map<double, Event*> endPoints;
并在两者中使用std::find算法并合并结果。
只是寻找一个建议,这是一个好的解决方案还是有更聪明的方法。
编辑:
重新考虑,它更复杂。这是预期结果的示例
- L
|---Ev1---| |---Ev3---| |---Ev5---|
|---Ev2---| |---Ev4---|
| |
L R
在这里,我想获得 Ev2(在范围内结束)、Ev3(在范围内发生)和 Ev4(在范围内开始)
- L
|---Ev1---| |---Ev3---| |---Ev5---|
|---Ev2---| |---Ev4---|
| |
L R
在这里,我想获得 Ev3,因为它当前在该范围内运行,而 Ev4 在该范围内开始运行
- L == R:如果我想知道某个时间点发生了什么
|---Ev1---| |---Ev3---| |---Ev5---|
|---Ev2---| |---Ev4---|
|
LR
这里我只想要 Ev2,因为它是当前唯一运行的。
【问题讨论】:
-
看看 Boost.ICL。
-
您仍然可以查看 Boost 以了解它们如何实现您的目标。然后使用这些想法提出/研究您自己的实现。
-
你写
L <= v1 <= R or L <= v2 <= R,然后开始、发生或结束,但这不一样。对于发生,你需要v1 <= R and L <= v2 -
@Yola:考虑到这一点,刚刚编辑了第一篇文章
-
您是否在寻找区间树:en.wikipedia.org/wiki/Interval_tree?