ベクトルから要素を 1 つずつ消去するのは非常に非効率的です。これは、消去するたびに、すべての要素を 1 つ下にコピーしてから、1 つ小さいベクトルを再割り当てする必要があるためです。
代わりに、erase-remove イディオムを使用してください。このプロセスでは、後のアイテムを移動して以前のアイテムを置き換えることにより、アイテムを削除します (元の順序が維持されます)。アイテムが削除された後、単一の消去 (リストの最後) を実行して、n 個のアイテム (n は削除されたアイテムの数) だけ小さい新しいベクトルを再割り当てします。
サンプル実装:
template <class _FwdIt, class _FwdIt2>
_FwdIt remove_by_index(_FwdIt first,
_FwdIt last,
_FwdIt2 sortedIndexFirst,
_FwdIt2 sortedIndexLast)
{
_FwdIt copyFrom = first;
_FwdIt copyTo = first;
_FwdIt2 currentIndex = sortedIndexFirst;
size_t index = 0;
for (; copyFrom != last; ++copyFrom, ++index)
{
if (currentIndex != sortedIndexLast &&
index == *currentIndex)
{
// Should delete this item, so don't increment copyTo
++currentIndex;
print("%d", *copyFrom);
}
else
{
// Copy the values if we're at different locations
if (copyFrom != copyTo)
*copyTo = *copyFrom;
++copyTo;
}
}
return copyTo;
}
サンプル使用法:
#include <vector>
#include <algorithm>
#include <functional>
int main(int argc, char* argv[])
{
std::vector<int> myVector;
for (int i = 0; i < 10; ++i)
myVector.push_back(i * 10);
std::vector<size_t> deleteIndex;
deleteIndex.push_back(3);
deleteIndex.push_back(6);
myVector.erase(
remove_by_index(myVector.begin(), myVector.end(), deleteIndex.begin(), deleteIndex.end()),
myVector.end());
for (std::vector<int>::iterator it = myVector.begin();
it != myVector.end(); ++it)
{
printf("%d ", *it);
}
return 0;
}
要旨: https://gist.github.com/eleven41/5746079
ここでテスト: http://ideone.com/0qkDw5