我应该使用哪种STL来完成这项任务?

时间:2016-04-20 12:46:34

标签: c++ list stack queue

我需要一个必须添加/删除一些结构的队列,例如:

struct MyObject
{
  int offset;
  BYTE status, data1, data2;
  double beatPos;

  enum Status
  {
    isOff = 8,
    isOn = 9,
  };
}   

当我.Add()一个元素时,由于beatPos值,该队列必须将元素放在正确的位置,该值必须从下面排序(队列的顶部,即下一个)元素我会弹出)到鞋帮(我将从中提取的最后一个元素)。

我看到有std::priority_queue,但我不确定我是否可以选择订购字段。

此外,一旦我在列表中添加了一些结构,我想删除第一个元素(例如)beatPos=1,567(例如,可能位于列表中间;不一定;在开头)。

任何线索?

2 个答案:

答案 0 :(得分:6)

你想要的是std::multiset。它需要一个比较模板参数,对于容器要存储的类型,它默认为std::less,但您可以指定不同的比较器。为此,我们可以创建一个lambda,它将比较两个MyObject并根据beatPos成员返回哪个对象具有更高的优先级

auto my_compare = [](const MyObject & lhs, const MyObject & rhs)
                    {
                        return lhs.beatPos < rhs.beatPos;
                    }

然后我们可以像

那样使用它
std::multiset<MyObject, decltype(my_compare)> data(my_compare);

这将为您提供一个有序容器,可以存储多个具有相同beatPos的对象,并允许您访问容器的中间位置。

答案 1 :(得分:5)

您可以将std::multiset与用户定义的比较器一起使用。例如:

bool MyObjectComp(const MyObject& lhs, const MyObject& rhs) {
    return lhs.beatPos < rhs.beatPos;
}

typedef std::set<MyObject, MyObjectComp> MyObjectSet;

现在MyObjectSet内的排序始终从最低到最高beatPos。您可以使用lower_bound()upper_bound()进行搜索,然后使用begin()获取最小值。

请注意,由于double值(IEEE浮点数)的性质,准确比较可能无效,因此您不一定要说mySet.find(0.5),但可以说mySet.upper_bound(0.49999)

同样的用户定义比较器也可用于priority_queue,但该容器不支持按值搜索元素,这是您的要求之一。