简体   繁体   English

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

[英]C++ — How to remove the element with such a condition efficient from a STL container?

Given the following code, 鉴于以下代码,

struct Student
{
 int score;
}

queue<Student> stdQueue;

I want to remove the students from the list if the score of the student is less than the previous one. 如果学生的分数低于前一个,我想从列表中删除学生。 How to do this efficient? 如何做到这一点有效?

For example 例如

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

Get 得到

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

You could write a custom predicate and use remove_if . 您可以编写自定义谓词并使用remove_if The predicate could be a functor that always stores the score of the previous Student . 谓词可以是一个总是存储前一个Student score的仿函数。 Something like this: 像这样的东西:

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;
};

As Neil points out, this is not possible with an std::queue . 正如Neil指出的那样,使用std::queue是不可能的。 It would, however, work with sequences like a deque , list , set or vector (anything that has begin() and end() ). 但是,它可以使用像dequelistsetvector这样的序列(任何有begin()end()序列)。

If you want to do it with a queue , do it like this: 如果你想用queue来做,那就这样做:

  1. Remove the first element from the queue (using pop ). 从队列中删除第一个元素(使用pop )。
  2. Compare the score to the new first element in the queue (access the first element using front ). 将得分与队列中的新第一个元素进行比较(使用front访问第一个元素)。
  3. If the score is greater, insert the element again at the back (using push ), otherwise discard it. 如果得分较高,请在后面再次插入元素(使用push ),否则丢弃它。
  4. Again from 1. until you have the first element at the front again. 再次从1.直到你再次在前面的第一个元素。

To make sure you do not process any element twice, you can do this in a loop that counts up to the original size of the queue. 要确保不处理任何元素两次,可以在循环中执行此操作,该循环计数到队列的原始大小。

A queue is not the right object for this type of thing. 对于这种类型的事物,队列不是正确的对象。 You should use either a priority queue, or a custom queue wrapping a linked-list that would allow you to-do such an operation. 您应该使用优先级队列或包装链接列表的自定义队列,以允许您执行此类操作。 The STL's queue implementation requires that you only access the front and back elements, and accessing any other elements requires the removal of any objects between the front-most element and the element right before the desired element you want from the queue. STL的队列实现要求您只访问前后元素,并且访问任何其他元素需要删除最前面的元素和您想要从队列中所需的元素之前的元素之间的任何对象。 So there would be quite a hassle pulling out a bunch of temporary objects, and then pushing them back in, in order to compare the objects and see which ones should be removed. 因此,将一堆临时对象拉出来然后将它们推回来会非常麻烦,以便比较对象并查看应删除哪些对象。

The priority queue on the other-hand is already sorted internally, so the front and back objects would either be the largest and smallest objects in the queue, or vice-versa. 另一方面的优先级队列已经在内部排序,因此前后对象将是队列中最大和最小的对象,反之亦然。 All other objects in-between would also be sorted. 中间的所有其他对象也将被排序。 So as you pop elements off the front of the queue, they would come off in an increasing or decreasing order, depending on what comparison function you've initialized the priority queue with. 因此,当您从队列前面弹出元素时,它们会以递增或递减的顺序关闭,具体取决于您初始化优先级队列的比较函数。

You can read-up on the use of a priority queue here at cplusplus.com . 您可以在cplusplus.com上阅读有关使用优先级队列的信息

I think the algorithm is something like the following: 我认为算法类似于以下内容:

  1. Get the current size of the queue, call it N. 获取队列的当前大小,称之为N.
  2. pop 1 element, call it Prev pop 1元素,称之为Prev
  3. push Prev 推上一个
  4. repeat N-1 times 重复N-1次
    1. pop element, call it Cur pop元素,称之为Cur
    2. if Cur >= Prev, push Cur 如果Cur> = Prev,则按Cur
    3. set Prev = Cur 设置Prev = Cur

Basically rotate through the entire queue, but only push back the elements that compare favorably with the preceeding one. 基本上在整个队列中旋转,但只能推回与前一个队列相比有利的元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM