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

これは、タイプに適した演算子<があることを前提としています。そうでない場合は、比較関数を作成し、それをmax_elementの3番目のパラメーターとして提供します。

編集:

この作業も、この場合、要素を明示的に検索していずれかの側の要素を削除する代わりに、1つの要素を検索するように並べ替えてから、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

コードを書き直して、1つの削除のみを行うだけです。

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 に答える
0

largest次のように、最初の要素として定義し、2番目の要素から反復を開始できます。

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

ただし、ここにはバグがあり、products.erase(largest)呼び出された後はit無効になるため、ここで提案されている他のアプローチを使用することをお勧めします。

于 2012-11-08T02:29:09.127 に答える