2011-10-23 45 views
3

C++では、どのようにして要素をベクトルから削除できますか?Vectorからの要素の消去

  1. すなわちベクトル要素が最後の要素S。T.で削除する
  2. スワップサイズを変更させ、右のそれがどこから削除

(1)については、私は次のことを試してみましたが、それが何をしているかはわかりません(removeItem()に渡された項目を削除)を行うことになっている、それは非常にエレガントでいないようです:eraseが何をするかだ

vector<Item*> items;    
// fill vector with lots of pointers to item objects (...) 

void removeItem(Item * item) { 
    // release item from memory 
    if (int i = getItemIdIfExists(item) != -1) { 
     items.erase (items.begin()+i); 
    } 
} 

int getItemIdIfExists(Item * item) { 
    // Get id of passed-in Item in collection 
    for (unsigned int i=0; i<items.size(); i++) { 
     // if match found 
     if (items[i] == item)  return i; 
    } 
    // if no match found 
    return -1; 
} 

答えて

2
void removeItem(Item*item){ 
    for(int i=0; i<items.size(); i++){ 
    if (items[i]==item){ 
     swap(items[i], items.back()); 
     items.pop_back(); 
     return; 
    } 
    } 
} 

順序は重要ではありません場合はけれども、なぜちょうどstd::setを使用していませんか?

+0

ありがとう、それは私の問題を解決します。また、1つの要素だけを削除します(これは私が望むものです)。何らかの理由で私自身のコードが複数の要素を削除したようです。セットに関しては、なぜ私はそれを使用するのかよく分かりません!この特定の場合を除いて、私のアクセスは主に順次です(つまり、すべての項目が更新され、すべての項目がレンダリングされます)。 – Ben

+0

どのように使用しているのかわかりませんでしたので、セットからアイテムを削除する方がベクトルよりも速くなると考えていました(ベクトル全体をシフトしていなくても、私の 'removeItem ')、しかしあなたがあまりにも多くの削除をしない場合は、ベクトルでうまくいくはずです。 – Vlad

+1

さて、 'items'はゲーム内のコレクタブルなので、フレームごとに順次更新され、レンダリングされますが、実際に収集されるたびに削除されます。だから私は、ベクトルはこの場合には良い選択だと思います。 – Ben

1

Delete it right from where it is, i.e. let the vector resize

を。

removeが、それは周りのすべてのコピーを伴わないので、それは残りのオブジェクトの順序を保持することを除いて、何をするかだ

Swap the element to be deleted with the last element s.t. pop_back() can be used (which I hope doesn't involve copying everything around...)

items.erase(
    std::remove(
     items.begin(), items.end() 
     , item 
    ) 
    , items.end() 
); 

あなたのコードは、これは実際にだけでなく最初の1で、item大切すべての項目を削除することであることとの違い:あなたは何をやったか

は次のように書くことができます。

+0

あなたのコードでは、次のエラーが表示されます: ''変換できません '' __gnu_cxx :: __ normal_iterator > 1 'から' int remove(const char *) '|' – Ben

+0

これは 'remove'とは全く異なります。残りのアイテムの順序が保持されるため、コピーが必要です。 – UncleBens

+0

@UncleBens:答えを編集します。ありがとうございました。 –

8

標準削除+イディオムを消去値によって要素を削除:すべてeraseesは端にあり、erasee範囲の先頭にイテレータを返すよう

#include <vector> 
#include <algorithm> 

std::vector<int> v; 
v.erase(std::remove(v.begin(), v.end(), 12), v.end()); 

remove要素を並べ替え、およびeraseは実際には要素をコンテナから削除します。

これは、vectorのような連続ストレージコンテナを使用すると効率的です。特に、同じ値の複数の要素がすべて1回の消去で消去される場合は効率的です。

+0

'v.remove'ではなく' remove'だけでいいのですか? – Vlad

+0

@Vlad:ありがとう、修正済み! –

関連する問題