[英]Add things to an std::map by time range but interrogate by time value
我正在建立一個std :: map對象,該對象將一系列時間范圍(鍵)鏈接到對象。
我的目的是確保不能將兩個重疊的時間范圍值添加到此地圖中-我知道我可以通過創建一個比較器函數來實現此目的,如果有重疊,該函數將返回true並將其作為第三個比較器模板項傳遞給std :: map。
但是,我想基於單個時間點而不是范圍來查找值。
我想我需要重寫一個運算符,但是我不確定哪個-有什么想法嗎?
我需要快一點,因為我認為辦公室即將關閉,對於任何缺少細節/代碼的人都表示歉意。
比較兩個范圍時,您會得到三種可能的結果:
您需要對比較函數進行編碼以反映這種關系。
bool RangeLess(const range &r1, const range &r2)
{
return r1.end < r2.start;
}
那很容易,不是嗎? 如果存在任何重疊,則RangeLess(r1,r2)
和RangeLess(r2,r1)
都將返回false
,並且兩者將被視為等效。 如果map
已經存在等效項,則嘗試插入map
將失敗。
要查找單個時間,請使用起始值和結束值相同的范圍。
添加一個接受單個值(時間)並生成一個由單點組成的范圍的構造函數-開始和結束是相同的。
覆蓋范圍的運算符==,因此如果范圍重疊,則返回true,否則返回false。
現在,您可以查找向其傳遞單個值(時間)的鍵,默認情況下會構造適當的范圍,如果范圍重疊,則返回true。
在這種情況下,我建議使用按結束時間排序的向量或雙端隊列(這會優化“調度”盡可能多的間隔),並簡單地迭代列表,跳過重疊的項目:
#include <string>
#include <deque>
#include <algorithm>
using Timepoint = unsigned; // std::chrono::system_clock::time_point;
struct Entry {
Timepoint start, end;
std::string data;
};
#include <iostream>
int main()
{
std::deque<Entry> schedule {
{ 77472, 77504, "A" },
{ 77301, 77371, "B" },
{ 77406, 77439, "C" },
{ 77270, 77303, "D" },
{ 77302, 77570, "E" },
};
// order by end time_point
std::sort(begin(schedule), end(schedule), [](Entry const& a, Entry const& b) { return a.end < b.end; });
// now, iterate the schedule entries, skipping overlapping items
for(auto it = begin(schedule); it != end(schedule); )
{
auto const& entry = *it;
std::cout << "entry: " << entry.data << " from " << entry.start << " to " << entry.end << "\n";
// find next entry that doesn't overlap:
while (++it != end(schedule))
if (it->start > entry.end)
break;
}
}
該算法可能有一個名字:它基本上是一種調度算法,它通過始終調度將很快完成的下一個條目來優化作業的數量(而不是例如總的“占用”間隔)。
上面的代碼打印出來:( 在Coliru上直播 ):
entry: D from 77270 to 77303
entry: C from 77406 to 77439
entry: A from 77472 to 77504
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.