2011-10-23 128 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:謝謝,修正! –