我有一个大型图像数据集,在每个图像捕获start_time
和stop_time
已知并编码为双精度的特定时间拍摄。
我想根据模拟时间将每个连续图像加载到我的模拟中,即 - 检查当前模拟时间是否在开始/停止间隔内。
我想为此使用地图,其中键是std::pair<double, double>
的开始&amp;停止时间,值是图像的完整路径。
std::map<std::pair<double, double>, std::string> _sequence; // t1, t2 and full path
我的问题: 如何搜索这样的地图以查找_currentTime是否在区间对内?
答案 0 :(得分:2)
首先,如果要搜索包含是您想要做的主要事情,请不要使用map
键入std::pair<double, double>
。这不是一个对数据结构有意义的操作。
但是如果你坚持,代码看起来就像这样(在C ++ 11中):
bool isWithinInterval() const {
for (const auto& pr : _sequence) {
if (_currentTime >= pr.first.first && _currentTime <= pr.first.second) {
return true;
}
}
return false;
}
Pre-C ++ 11,同样的想法,只是略有不同的循环语法。理想情况下,我们会使用std::find_if
,但表达地图value_type
会很麻烦。但是在C ++ 14中,没有这样的麻烦:
auto it = std::find_if(_sequence.begin(),
_sequence.end(),
[_currentTime](const auto& pr) {
return _currentTime >= pr.first.first && _currentTime <= pr.first.second;
});
return it != _sequence.end();
或者只是:
return std::any_of(_sequence.begin(), _sequence.end(),
[_currentTime](const auto& pr) {
return _currentTime >= pr.first.first && _currentTime <= pr.first.second;
});
答案 1 :(得分:2)
一种方法可能不使用std::map<std::pair<double, double>, std::string>
而是使用std::map<double, std::pair<double, std::string>>
:您使用m.lower_bound(current_time)
来查找一系列元素的开头current_time
适合的地方。然后你走迭代器直到它到达终点,落入相关范围,或超出结束时间:
auto it = _sequence.lower_bound(current_time);
for (; it != _sequence.end() && current_time <= it->second; ++it) {
if (it.first <= current_time) {
// found a matching element at it
}
}
使用带有std::pair<double, double>
键的布局需要第二次出现。不过,您可以使用std::make_pair(current_time, current_time)
。
答案 2 :(得分:0)
double search = 0.; /* or some other value */
bool found = false;
for ( auto & key_value_pair : _sequence ) {
// key_value_pair.first == map key
// key_value_pair.second == key's associated value
if ( key_value_pair.first.first <= search || search <= key_value_pair.first.second ) {
found = true;
break;
}
}
if ( found ) {
/* it's within an interval pair! */
} else {
/* it's not within an interval pair! */
}
我建议您同时查看boost::icl
答案 3 :(得分:0)
如果可能,请不要使用std :: pair作为密钥。它作为一个键并不真正有意义,因为你最终会遇到两个重叠范围映射到同一个元素的情况。
无论如何,这是我如何实现这样一个问题的解决方案。 lower_bound
/ upper_bound
是您的朋友。此外,您可以通过在停止时间键入值来避免反向迭代器技巧。
#include <map>
#include <stdio.h>
struct ImageStuff
{
double startTime;
double stopTime;
char data[1000];
};
typedef std::map<double, ImageStuff> starttime_map_type;
starttime_map_type starttime_map;
ImageStuff & MakeImage (double start, double stop) {
ImageStuff newImage;
newImage.startTime = start;
newImage.stopTime = stop;
return starttime_map[start] = newImage;
}
starttime_map_type::iterator FindByTime (double time) {
starttime_map_type::reverse_iterator i = starttime_map_type::reverse_iterator(starttime_map.upper_bound(time));
if (i == starttime_map.rend() || time > i->second.stopTime) {
printf ("Didn't find an image for time %f\n", time);
return starttime_map.end();
}
else {
printf ("Found an image for time %f\n", time);
return i.base();
}
return starttime_map.end();
}
int main (void)
{
MakeImage (4.5, 6.5);
MakeImage (8.0, 12);
MakeImage (1, 1.2);
auto i = FindByTime(3);
i = FindByTime(4.5);
i = FindByTime(9);
i = FindByTime(15);
return 0;
}