3

给定一个像这样的向量:

struct product {
    float price;
    float shipping;
};

vector<product> products;

如何从向量中删除所有产品,除了最大比率的shipping产品price

我尝试将迭代器保持到迄今为止发现的最高迭代器...

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,但据我所知,没有真正的方法可以做到这一点(如何检查迭代器是否已初始化?)。

有什么建议么?

4

3 回答 3

4
 vector<product> products;
 //populate products

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

这假设您有一个适合您的类型的 operator<,如果没有,请创建一个比较函数并将其作为第三个参数提供给 max_element。

编辑:

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

 vector<product> products;
 //populate products
 std::nth_element(
      products.begin(), 
      products.begin()+1, 
      products.end(), 
      std::greater<product>()
 );
 products.resize(1u);
于 2012-11-07T23:22:43.670 回答
0

您可以定义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会失效,所以你最好采用这里其他建议的方法。

于 2012-11-08T02:29:09.127 回答
0

只需重写代码以仅进行一次删除

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);
于 2012-11-07T23:23:32.553 回答