C ++ - 如何从STL容器中删除具有这种条件效率的元素?

时间:2011-05-19 20:10:14

标签: c++ stl

鉴于以下代码,

struct Student
{
 int score;
}

queue<Student> stdQueue;

如果学生的分数低于前一个分数,我想从列表中删除学生。如何有效地做到这一点?

例如

S1(100) <= S2(55) <= S3(200) <= S4(4) <= S6(1000)

获取

S1 (100) <= S3(200) <= S6(1000)

3 个答案:

答案 0 :(得分:5)

您可以编写自定义谓词并使用remove_if。谓词可以是一个总是存储前一个score的{​​{1}}的仿函数。像这样:

Student

正如尼尔指出的那样,class ScoreLessThanPrevious { public: ScoreLessThanPrevious() : isFirst(true), previousScore(0) {} bool operator()(const Student & s) { if (isFirst) { isFirst = false; return false; } else { boolean retval = s.score < previousScore; previousScore = s.score; return retval; } } private: bool isFirst; int previousScore; }; 无法做到这一点。但是,它可以使用std::queuedequelistset等序列(具有vectorbegin()的任何内容)。

如果您想使用end()执行此操作,请执行以下操作:

  1. 从队列中删除第一个元素(使用queue)。
  2. 将得分与队列中新的第一个元素进行比较(使用pop访问第一个元素)。
  3. 如果分数较高,请在后面再次插入元素(使用front),否则将其丢弃。
  4. 再次从1.直到你再次在前面有第一个元素。
  5. 为了确保您不处理任何元素两次,您可以在一个循环中执行此操作,该循环计算到队列的原始大小。

答案 1 :(得分:1)

队列不是此类事物的正确对象。您应该使用优先级队列或包装链接列表的自定义队列,以允许您执行此类操作。 STL的队列实现要求您只访问前后元素,并且访问任何其他元素需要删除最前面的元素和您想要从队列中所需的元素之前的元素之间的任何对象。因此,将一堆临时对象拉出来然后将它们推回来会非常麻烦,以便比较对象并查看应删除的对象。

另一方面的优先级队列已经在内部排序,因此前后对象将是队列中最大和最小的对象,反之亦然。中间的所有其他对象也将被排序。因此,当您从队列前面弹出元素时,它们会以递增或递减的顺序关闭,具体取决于您初始化优先级队列的比较函数。

您可以阅读使用优先级队列here at cplusplus.com

答案 2 :(得分:1)

我认为算法类似于以下内容:

  1. 获取队列的当前大小,将其命名为N。
  2. 弹出1个元素,称之为Prev
  3. push Prev
  4. 重复N-1次
    1. pop元素,称之为Cur
    2. 如果Cur&gt; = Prev,则按Cur
    3. 设置Prev = Cur
  5. 基本上在整个队列中旋转,但只会推回与前一个队列相比有利的元素。