我正在更改一些代码以使用命令模式,并将命令对象存储在队列中。这些命令需要在特定的时间执行,因此我将每秒迭代一次列表以查找要执行的命令。按时间排序的命令模式队列?
将有一个与每个命令对象相关的时间,我会检查这个时间与当前时间(在一个小的阈值内)。所以我需要从列表中删除命令对象,如果它的时间匹配,然后执行它。一般来说,在任何时候都会有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