【问题标题】:Remove all the vector elements apart from the 'largest' one删除除“最大”元素之外的所有矢量元素
【发布时间】:2012-11-07 23:20:32
【问题描述】:

给定一个像这样的向量:

struct product {
    float price;
    float shipping;
};

vector<product> products;

除了shippingprice 比率最大的产品之外,如何从向量中删除所有产品?

我尝试将迭代器保持到目前发现的最高迭代器...

vector<product>::iterator it = products.begin();
vector<product>::iterator largest = products.begin();

while (it != products.end())
{
    if (it->shipping / it->price > largest->shipping / largest->price)
    {
        products.erase(largest);
        largest = it;
        ++it;
    }
    else
    {
        it = products.erase(it);
    }
}

这一切都很好,但是如果向量中的第一个元素具有最高的比率(它被删除),它就会失败。如果largest 未初始化,然后在if 语句中检查它,我可以解决这个问题(我认为),但据我所知(How to check if the iterator is initialized?)没有真正的方法。

有什么建议吗?

【问题讨论】:

  • 矢量有多大?
  • 只需将it初始化为products.begin() + 1即可。
  • 不太大...最多 10 个

标签: c++ stl vector


【解决方案1】:
 vector<product> products;
 //populate products

 products.erase(
      products.begin(),
      std::max_element(
          product.begin(), 
          producted.end()
      )
 );
 products.resize(1u);

这假设您有一个适合您的类型的运算符

编辑:

这项工作也是如此,在这种情况下,它不是显式查找元素并删除任一侧的元素,而是排序找到 1 个元素,然后我们可以进行一次擦除。

 vector<product> products;
 //populate products
 std::nth_element(
      products.begin(), 
      products.begin()+1, 
      products.end(), 
      std::greater<product>()
 );
 products.resize(1u);

【讨论】:

  • 您不需要第二次调用max_element;第一个erase 之后的最大值是第一个元素。所以products.erase( ++products.begin(), products.end() ); 会成功的。
  • 我想我会使用std::swap 将最大元素移动到集合的开头,然后删除其余元素(可能会更快,尤其是vector)。
  • 这就是为什么我问向量有多大:D
  • products.assign(1, *std::max_element(product.begin(), producted.end());
  • @MooingDuck,不错,但您为 products 使用了三个不同的名称。
【解决方案2】:

只需重写代码,只一次删除

std::vector<product>::iterator largest = products.begin();

for (std::vector<product>::iterator it = products.begin(); it != products.end(); ++it)
{
    if (...) { largest = it; }
}

products.erase(it);

【讨论】:

  • 说我的向量有 10 个元素。一次删除如何删除其中的9个(只有一个比例最大的应该留下)?
  • @zoran119:你需要两遍。首先确定最大比率的,然后删除所有这些元素。为此使用std::remove_if
【解决方案3】:

您可以将largest定义为第一个元素并从第二个元素开始迭代,如下所示:

bool operator < (const struct product& p1, const struct product& p2)
{
   return p1.price/p1.shipping < p2.price/p2.shipping;
}

vector<product>::iterator largest = products.begin();
vector<product>::iterator it = products.begin();
++it;

while (it != products.end())
{
    if (*largest < *it)
    {
        products.erase(largest);
        largest = it;
        ++it;
    }
    else
    {
        it = products.erase(it);
    }
 }

但是这里有个bug,products.erase(largest)被调用后,it会失效,所以你最好采用这里其他建议的方法。

【讨论】:

    猜你喜欢
    • 2017-09-02
    • 1970-01-01
    • 2023-01-05
    • 2013-09-23
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多