2012-04-18 12 views
1

我正在更改一些代码以使用命令模式,并将命令对象存储在队列中。这些命令需要在特定的时间执行,因此我将每秒迭代一次列表以查找要执行的命令。按时间排序的命令模式队列?

将有一个与每个命令对象相关的时间,我会检查这个时间与当前时间(在一个小的阈值内)。所以我需要从列表中删除命令对象,如果它的时间匹配,然后执行它。一般来说,在任何时候都会有10个以下的命令。我应该使用什么样的集合数据结构,以及如何在迭代列表时删除命令对象?

回答

2

我想你想要使用priority queue。这是一个容器,可以让您拉取最高优先级的项目。就你而言,“更高优先级”是“首先发生”。

C++将一个优先队列建模为priority_queue容器适配器。这意味着其中有一些其他容器用于实际存储。该容器通常是vectordeque。 (需要随机访问迭代器。)默认为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()不会返回已移除的元素;它只是删除和破坏它。

+0

所以我想这会涉及到使用时间作为优先事项?由于我需要在特定时间(例如11:27:19 AM)运行命令,因此我是否要弹出命令,直到弹出超过当前时间的命令,然后将该命令放回队列中? – User 2012-04-18 23:28:36

+1

不,只要您的“比较”函数有效,优先级队列就会为您排序。所以当你抓住'top()'时,你就知道这是最高优先级的项目。只要确保'比较(a,b)'或'a 2012-04-18 23:33:56

+0

请注意,'<'时间的通常定义将不起作用,因为它稍后定义为“小于”。所以你可能只想为你的类'T'定义自己的'<'。 – 2012-04-18 23:35:20

1

迈克解决方案的替代方案是使用有序地图,在STL的情况下,它只是一个map。你可以把时间作为一个关键和命令作为价值。根据你的情况,它可能比队列更方便。

如果允许两个命令同时执行,则应使用multimap

multimap<time_t, Command> schedule; 

schedule.insert(pair<time_t, Command>(123456, formatHDDCommand)); 
+0

基于地图的解决方案存在的问题是我需要允许有一点滑动,所以如果当前时间超过目标时间1或2秒并且该命令仍然没有执行,我仍然需要它执行。 – User 2012-04-19 00:26:49

+0

@用户当然!你不应该在地图上搜索确切的时间。相反,你有两个其他途径来利用multimap。首先,你可以选择'begin'或'end'(取决于时间表示)迭代器,并将其时间与当前时间进行比较。如果当前时间较长,则执行该命令。根据需要重复此步骤。其次,可以使用当前时间的'find()'函数作为参数,并从'find()'返回的迭代器开始迭代。 'find()'会“截断”命令,这个时间还没到。 – doc 2012-04-19 00:54:22

+0

啊我看到了,我以为你是在暗示一个确切的关​​键匹配,但是你正在使用一张地图,因为它的顺序属性不是 – User 2012-04-19 02:10:26