考えるからアイテムの既知のサブセットを削除:実行するコードを記述するための最も効率的な/クリーンな方法は何C++ベクトル
struct Item { int id; ... };
std::vector<Item> items;
std::vector<int> idsToRemove;
削除(注文を保持している間)? remove_if
を使用して
、これは次のようになります。
items.erase(std::remove_if(items.begin(), items.end(),
[&](const Item& i) {
return std::find(idsToRemove.begin(), idsToRemove.end(), i.id)
!= idsToRemove.end();
}), items.end());
もう一つの方法は、次のようになります。
for (auto id : idsToRemove)
{
items.erase(std::remove(items.begin(), items.end(), id), items.end());
// or items.erase(std::find(items.begin(), items.end(), id));
// provided that we know id always exists in items
}
どちらもこれらの特に素敵な感じ(と彼らの両方がO(N * M)に見えます)第二のものは最初のものよりもきれいに見えます。より良い方法がありますか?
(どちらのベクトルもソートされていないが、どちらもidsToRemove
は、items
に表示されているのと同じ順序でIDのサブセットであり、両方の配列が小さいことがわかっている。あそこに適した何か。)
消去の削除を、* next * IDと一致する最初の項目で区切られた部分範囲に制限することができます。それを背中から行うと、動く量を最小限に抑えることができます。 –
いいえ、記載されているように、アレイは通常小さいです。私は主にコードの簡潔さを求めていますが、不必要に非効率的であることを望んでいません。 – Miral
大規模な任意のリストだった場合は、idsToRemoveというハッシュまたはブルームフィルタを作成しているため、アイテムを繰り返し処理するときにO(1)の時間にチェックすることができます。しかし、同じオーダーのサブセット保証があれば、それは全く不要です。あなたはベクトルが小さいと言って以来、O(NM)はそれほど悪くないわけではありませんが、私は1201ProgramAlarmの答えに投票しました。それはO(N)の空間と時間ですが、あなた自身で書く必要があります。私は上記のあなたの迅速なソリューションの本当の問題は、ベクトルから単一項目の束を削除すること自体が遅いということです。 –