我正在更改一些代碼以使用命令模式,並將命令對象存儲在隊列中。這些命令需要在特定的時間執行,因此我將每秒迭代一次列表以查找要執行的命令。按時間排序的命令模式隊列?
將有一個與每個命令對象相關的時間,我會檢查這個時間與當前時間(在一個小的閾值內)。所以我需要從列表中刪除命令對象,如果它的時間匹配,然後執行它。一般來說,在任何時候都會有10個以下的命令。我應該使用什麼樣的集合數據結構,以及如何在迭代列表時刪除命令對象?
我正在更改一些代碼以使用命令模式,並將命令對象存儲在隊列中。這些命令需要在特定的時間執行,因此我將每秒迭代一次列表以查找要執行的命令。按時間排序的命令模式隊列?
將有一個與每個命令對象相關的時間,我會檢查這個時間與當前時間(在一個小的閾值內)。所以我需要從列表中刪除命令對象,如果它的時間匹配,然後執行它。一般來說,在任何時候都會有10個以下的命令。我應該使用什麼樣的集合數據結構,以及如何在迭代列表時刪除命令對象?
我想你想要使用priority queue。這是一個容器,可以讓您拉取最高優先級的項目。就你而言,「更高優先級」是「首先發生」。
C++將一個優先隊列建模爲priority_queue
容器適配器。這意味着其中有一些其他容器用於實際存儲。該容器通常是vector
或deque
。 (需要隨機訪問迭代器。)默認爲vector
。所以,你可以聲明:
std::priority_queue<T, vector<T>, Compare> queue;
其中T
是你的元素,Compare
是比較兩個T
元素,並返回true
如果第一個比第二低優先級的功能。如果您爲T
類型定義operator <
,它變得更簡單:
std::priority_queue<T> queue;
queue.push(item);
queue.top()
queue.pop();
請注意,pop()
不會返回已移除的元素;它只是刪除和破壞它。
邁克解決方案的替代方案是使用有序地圖,在STL的情況下,它只是一個map
。你可以把時間作爲一個關鍵和命令作爲價值。根據你的情況,它可能比隊列更方便。
如果允許兩個命令同時執行,則應使用multimap
。
multimap<time_t, Command> schedule;
schedule.insert(pair<time_t, Command>(123456, formatHDDCommand));
基於地圖的解決方案存在的問題是我需要允許有一點滑動,所以如果當前時間超過目標時間1或2秒並且該命令仍然沒有執行,我仍然需要它執行。 – User 2012-04-19 00:26:49
@用戶當然!你不應該在地圖上搜索確切的時間。相反,你有兩個其他途徑來利用multimap。首先,你可以選擇'begin'或'end'(取決於時間表示)迭代器,並將其時間與當前時間進行比較。如果當前時間較長,則執行該命令。根據需要重複此步驟。其次,可以使用當前時間的'find()'函數作爲參數,並從'find()'返回的迭代器開始迭代。 'find()'會「截斷」命令,這個時間還沒到。 – doc 2012-04-19 00:54:22
啊我看到了,我以爲你是在暗示一個確切的關鍵匹配,但是你正在使用一張地圖,因爲它的順序屬性不是 – User 2012-04-19 02:10:26
所以我想這會涉及到使用時間作爲優先事項?由於我需要在特定時間(例如11:27:19 AM)運行命令,因此我是否要彈出命令,直到彈出超過當前時間的命令,然後將該命令放回隊列中? – User 2012-04-18 23:28:36
不,只要您的「比較」函數有效,優先級隊列就會爲您排序。所以當你抓住'top()'時,你就知道這是最高優先級的項目。只要確保'比較(a,b)'或'a 2012-04-18 23:33:56
請注意,'<'時間的通常定義將不起作用,因爲它稍後定義爲「小於」。所以你可能只想爲你的類'T'定義自己的'<'。 – 2012-04-18 23:35:20