2015-01-06 76 views
3

我有一個很大的圖像數據集,在特定的時間拍攝,其中每個圖像捕獲start_timestop_time已知並編碼爲雙打。 我想根據模擬時間將每個連續的圖像加載到我的模擬中,即 - 檢查當前模擬時間是否落入開始/停止時間間隔內。std :: pair作爲地圖中的關鍵字

我想爲此使用地圖,其中關鍵是std::pair<double, double>開始&停止時間,值是圖像的完整路徑。

std::map<std::pair<double, double>, std::string> _sequence; // t1, t2 and full path 

我的問題: 如何搜索這樣的地圖找到,如果_currentTime是時間間隔對中?

+1

'的std ::地圖<...>'是不是[範圍樹(http://en.wikipedia.org/wiki/Range_tree)... –

+0

你可能會需要編寫自定義比較HTTP:/ /msdn.microsoft.com/en-us/library/ms132092%28v=vs.110%29.aspx – gmlacrosse

+0

查看['boost interval container library'](http://www.boost.org/doc/)庫/ 1_57_0 /庫/ ICL/DOC/HTML/index.html的)。從文檔:An ['interval_map'](http://www.boost。org/doc/libs/1_57_0/libs/icl/doc/html/boost/icl/interval_base_map.html)是一個以間隔值對映射實現的映射 –

回答

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; 
} 

預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; 
        }); 
+0

I我實際上是循環來回使用哪個數據結構。你有什麼建議,哪些是最優的,而且很快實施?我真的很喜歡使用STL的東西。 (即不寫我自己的二叉樹類) – mike

+0

@mike我不認爲有標準庫中的任何間隔。它實際上只是有序的容器和關聯容器。 – Barry

+0

我想學習如此 - 爲什麼在這種情況下使用地圖不好?我對這個問題的任何解決方案開放它只是我多多少少的菜鳥和地圖似乎是一個相當簡單的方法... – mike

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

+0

謝謝你我肯定會。 – mike

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)

+0

在你的例子中,你的意思是關鍵是start_time,而pair中的第一個是end_time? – mike

+0

林問我可能需要存儲停止/結束時間,因爲我認爲會需要實際模擬拍攝圖像所花的時間(淡入或類似) – mike

+0

是,關鍵是開始時間,所有其他數據都存儲在記錄中。如果這不符合您的需求,您可能需要查看範圍樹,這些範圍樹專門用於處理間隔。 –

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; 
} 
+0

問題給你:我想實現這個,但它在'return starttime_map [start] = newImage;'上崩潰了 - 我需要在使用MakeImage函數之前初始化或者用starttime_map做其他事情嗎? (否則其逐行寫入的內容) – mike

+0

嘗試將其分解爲'ImageStuff&result = starttime_map [start]; result = newImage;返回結果;' – QuestionC

相關問題