2011-10-23 126 views
3

在C++中,如何从矢量中删除元素?从矢量中删除元素

  1. 从那里是删除是正确的,即让矢量调整
  2. 交换元件与所述最后一个元素S.T.被删除pop_back()可以使用(我希望不涉及复制周围的一切...)

对于(1),我试过以下,但我不太确定它是否做了什么这是应该做的(删除传递到的removeItem()项),它似乎并不很优雅:

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

谢谢,解决了我的问题。它也只会删除一个元素(这是我想要的)。由于某种原因,我自己的代码似乎删除了多个元素。关于这一套,我不太清楚为什么我会使用它!?除了这个特殊情况,我的访问主要是连续的(即所有项目都是更新,所有项目都被渲染等)。 – Ben

+0

我不确定你是如何使用它,所以我想从一个集合中移除项目会比从一个矢量中移除更快(即使我们没有移动整个矢量,它仍然是O(n)for'removeItem '),但如果你没有做太多删除,你应该很好的矢量。 – Vlad

+1

那么,'物品'在游戏中是可收集的,因此它们在每一帧都会被更新和渲染,而玩家实际收集这些物品时经常会被移除。所以我猜在这种情况下矢量是更好的选择。 – Ben

1

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

这就是erase一样。

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

这就是remove做,但它保留了剩余对象的顺序,因此它不涉及复制周围的一切。

你做了什么可以写成:

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

与您的代码是这将实际删除,而不只是第一个所有件,价值item,所不同。

+0

用你的代码我得到以下错误:'不能转换'__gnu_cxx :: __ normal_iterator <项目**,std :: vector <项目*,std :: allocator >>'为const char *'为参数' 1'到'int remove(const char *)'|' – Ben

+0

这不是什么'remove'。它涉及复制,因为它保留了剩余项目的顺序。 – UncleBens

+0

@UncleBens:我会编辑我的答案。谢谢。 –

8

标准删除+擦除成语由值删除元素:

#include <vector> 
#include <algorithm> 

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

remove重新排序的元素,使所有的erasees是在端部并返回迭代到erasee范围的开始,和erase实际上从容器中移除元素。

这与使用像vector这样的连续存储容器一样有效,特别是如果您有多个具有相同值的元素,并且所有元素都可以在一次清洗中清除。

+0

不应该只是'remove'而不是'v.remove'? – Vlad

+0

@Vlad:谢谢,修正! –