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

C++ -- How to remove the element with such a condition efficient from a STL container?

本文关键字:有效 元素 条件 删除 STL C++      更新时间:2023-10-16

给定以下代码,

struct Student
{
 int score;
}
queue<Student> stdQueue;

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

例如

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

获取

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

您可以编写自定义谓词并使用remove_if .谓词可以是始终存储前Student score的函子。像这样:

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::queue是不可能的。然而,它可以处理像dequelistsetvector这样的序列(任何有begin()end()的东西)。

如果你想用queue来做,这样做:

  1. 从队列中删除第一个元素(使用 pop )。
  2. 将分数与队列中新的第一个元素进行比较(使用 front 访问第一个元素)。
  3. 如果分数较大,请在后面再次插入元素(使用 push ),否则将其丢弃。
  4. 再次
  5. 从 1 开始,直到您再次在前面看到第一个元素。

若要确保不会对任何元素进行两次处理,可以在循环中执行此操作,该循环最多计算到队列的原始大小。

我认为算法如下所示:

  1. 获取队列的当前大小,将其称为 N。
  2. pop 1 元素,称之为 Prev
  3. 推送上一页
  4. 重复N-1次
    1. 流行元素,称之为 Cur
    2. 如果 Cur>= 上一页,则推送 Cur
    3. 设置上一个 = 库尔

基本上在整个队列中轮换,但只推回与前一个队列相比有利的元素。

队列

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

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

您可以在 cplusplus.com 阅读有关使用优先级队列的信息。