[英]std::pair as key in map
我有一個大型圖像數據集,在特定時間拍攝,每個圖像捕獲start_time
和stop_time
都已知並編碼為雙精度。 我想根據模擬時間將每個連續圖像加載到我的模擬中,即 - 檢查當前模擬時間是否在開始/停止間隔內。
我想為此使用一個映射,其中鍵是std::pair<double, double>
的開始和停止時間,值是圖像的完整路徑。
std::map<std::pair<double, double>, std::string> _sequence; // t1, t2 and full path
我的問題:如何搜索這樣的地圖以查找_currentTime是否在區間對中?
首先,如果搜索包含是您想要做的主要事情,請不要使用鍵入std::pair<double, double>
的map
。 這不是一個對數據結構有意義的操作。
但是,如果你堅持,代碼看起來像這樣(在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;
});
一種方法可能是不使用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::pair<double, double>
一個鍵需要第二次出現。 但是,您可以使用std::make_pair(current_time, current_time)
。
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
如果可能,請不要使用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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.