使用Boost ICL查找范围包含点的所有对象
Using Boost ICL to Find All Objects Whose Range Contains a Point
给定一个对象列表L,每个对象包含一个添加的时间、一个删除的时间、一个名称和一些其他字段。给定时间T,我想返回一个列表,该列表只包含来自L的对象,其中T落在对象的添加时间和删除时间之间(另外,我想同时搜索特定名称的所有对象,但如果使事情复杂化,则没有必要)。我该如何使用Boost的ICL呢?
假设你的对象看起来像
struct record {
std::string name;
using ptime = boost::posix_time::ptime;
ptime added, removed;
};
现在,让我们添加一个方便的方法,以便我们可以更轻松地处理时间间隔:
icl::interval<ptime>::interval_type validity() const {
icl::interval<ptime> x;
return x.right_open(added, removed);
}
一个简单的测试程序是这样的:
int main()
{
ptime const start(day_clock::local_day(), { });
std::vector<record> L {
{ "long" , start + hours(77) , start + days(7) } ,
{ "medium" , start + hours(200), start + hours(236) },
{ "short" , start + hours(220), start + hours(226) },
{ "ephemeral", start + hours(100), start + hours(101) },
};
for (ptime T = start; T <= (start + days(10)); T += hours(6))
{
std::cout << "nT:" << T << "t";
std::ostream_iterator<record> out(std::cout, ";");
std::copy_if(L.begin(), L.end(), out, [T](record const& r) { return icl::contains(r.validity(), T); });
}
}
在10天的范围内迭代时间点T
,以6小时为步长,并打印L
中匹配的对象,参见Live On Coliru
T:2014-Jun-06 00:00:00
T:2014-Jun-06 06:00:00
T:2014-Jun-06 12:00:00
T:2014-Jun-06 18:00:00
T:2014-Jun-07 00:00:00
T:2014-Jun-07 06:00:00
T:2014-Jun-07 12:00:00
T:2014-Jun-07 18:00:00
T:2014-Jun-08 00:00:00
T:2014-Jun-08 06:00:00
T:2014-Jun-08 12:00:00
T:2014-Jun-08 18:00:00
T:2014-Jun-09 00:00:00
T:2014-Jun-09 06:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-09 12:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-09 18:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-10 00:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-10 06:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-10 12:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-10 18:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-11 00:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-11 06:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-11 12:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-11 18:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-12 00:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-12 06:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-12 12:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-12 18:00:00 {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
T:2014-Jun-13 00:00:00
T:2014-Jun-13 06:00:00
T:2014-Jun-13 12:00:00
T:2014-Jun-13 18:00:00
T:2014-Jun-14 00:00:00
T:2014-Jun-14 06:00:00
T:2014-Jun-14 12:00:00 {medium, 2014-Jun-14 08:00:00, 2014-Jun-15 20:00:00};
T:2014-Jun-14 18:00:00 {medium, 2014-Jun-14 08:00:00, 2014-Jun-15 20:00:00};
T:2014-Jun-15 00:00:00 {medium, 2014-Jun-14 08:00:00, 2014-Jun-15 20:00:00};
T:2014-Jun-15 06:00:00 {medium, 2014-Jun-14 08:00:00, 2014-Jun-15 20:00:00};{short, 2014-Jun-15 04:00:00, 2014-Jun-15 10:00:00};
T:2014-Jun-15 12:00:00 {medium, 2014-Jun-14 08:00:00, 2014-Jun-15 20:00:00};
T:2014-Jun-15 18:00:00 {medium, 2014-Jun-14 08:00:00, 2014-Jun-15 20:00:00};
T:2014-Jun-16 00:00:00
可以看到,"ephemeral"
太短了,使用这种方法完全忽略了它!您可能希望遍历插槽中的时间,而不是时间点逐步:
for (auto Slot = icl::interval<ptime>::right_open(start, start + hours(6));
Slot.lower() <= (start + days(10));
Slot = icl::interval<ptime>::right_open(Slot.upper(), Slot.upper() + hours(6)))
{
std::cout << "nSlot:" << Slot << "t";
std::ostream_iterator<record> out(std::cout, ";");
std::copy_if(L.begin(), L.end(), out, [Slot](record const& r) { return icl::intersects(Slot, r.validity()); });
}
看到Live On Coliru也是,并观察"ephemeral"
如何不再错过:
...
Slot:[2014-Jun-09 18:00:00,2014-Jun-10 00:00:00) {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
Slot:[2014-Jun-10 00:00:00,2014-Jun-10 06:00:00) {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};{ephemeral, 2014-Jun-10 04:00:00, 2014-Jun-10 05:00:00};
Slot:[2014-Jun-10 06:00:00,2014-Jun-10 12:00:00) {long, 2014-Jun-09 05:00:00, 2014-Jun-13 00:00:00};
...
相关文章:
- 将包含C样式数组的对象初始化为成员变量(C++)
- 是否需要删除包含对象的"pair"?
- 如何在h文件中包含.o对象文件
- 将 C# 对象(包含静态对象成员)作为参数传递给 C++/CLI 程序
- C/C++ 包含点的宏参数(成员访问运算符)
- 根据 3D 对象的点和边生成其面
- 如何在构建时将 JSON 文件/对象包含在C++中
- 当对象包含其他对象的向量时,无法设置值
- 在矢量内创建一个对象,该对象由另一个对象包含
- 为什么在 C++ 中,当对象包含在另一个对象中时,复制构造函数被调用两次
- 当对象包含指针成员时,堆栈上的对象销毁出现分段错误
- 如果插槽对象包含互斥锁和条件变量,则 Boost signals2 connect() 调用编译失败
- 当包含对象包含unique_ptr时,如何删除向量的元素
- 计算 3D 对象与点之间的角度
- vector包含类对象,每个类对象包含3个字符串.我如何找到特定的字符串,然后删除整个元素
- 使用Boost ICL查找范围包含点的所有对象
- 自定义对象的STL集合,每个对象包含一个STL集合
- 有多少对象(包含 std::vectors)加载到 L1/L2/L3 缓存中
- 将主应用程序对象包含在 try-catch 块中捕获所有崩溃
- 使一个对象可点击(如果鼠标在对象区域内,点击)