2014-03-04 81 views
-1

我已經建立了使用控制檯來構建我有限的C++知識小Roguelike ASCII遊戲。當玩家對象的座標與一個物品(存儲在一個矢量中)相同時,它會設置它,移除物品並將10加到玩家的HP中。擦除元素從矢量擦除多個(C++)

程序開始了在房間9個項目。但是,每當我獲得物品時,它會刪除矢量中的前5個物品(但由於某種原因,它們仍然在屏幕上繪製),並將50增加到健康狀態。所以我剩下4件物品。下一次我得到一個物品時,它將刪除前兩個並將20增加到健康狀態。現在我剩下兩件物品。最後兩次,它一次刪除一個項目。

所以,從本質上講,矢量被減半,每次分裂,我得到一個項目。我已經收窄經歷了很多調試的問題,我敢肯定它是從這個塊的代碼來:

for(int i=0;i<ia.size();i++) //If the player touches an item 
{ 
     if(grid[p.getY()][p.getX()]==itm) 
     { 
      hp+=10; 
      cout << "Item "<<i<<" removed\n"; 
      swap(ia[i], ia.back()); 
      ia.pop_back(); 
      system("pause"); 
     } 
} 

我還在試圖找出載體,因此,如果有人能告訴我我做錯了什麼,我真的很感激它。 :)

+0

使用std ::矢量::抹去? – Stepan1010

+0

也許'打破;'內'如果(...)'有點幫助 – abiessu

+0

我也嘗試矢量::擦除爲好,但什麼都沒有改變。 – TheBeocro

回答

1

有意見暗示erase(),但請注意,它會逐個複製後面的數組元素以填充正在騰空的索引:您的對換方法可能會大大加快,如果您不在乎關於元素順序。

一個問題是,您將back()元素換成您要移除的元素所佔據的位置,然後遞增迭代器以測試下一個ia索引。這意味着從back()複製的項目是從來沒有自己測試 - 爲要避免i++swap後。當然,如果只有一個項目能永遠佔據發車位置,你可以break作爲abiessu評論....

下面是一些代碼,我想你想的作品:

#include <iostream> 
#include <vector> 

using namespace std; 

int main() 
{ 
    vector<int> ia{ 10, 20, 30, 40, 50, 60, 70 }; 
    for(size_t i=0;i<ia.size();) //If the player touches an item 
    { 
     if(ia[i] % 20) 
     { 
      cout << "Item "<<i<<" removed\n"; 
      swap(ia[i], ia.back()); 
      ia.pop_back(); 
      continue; 
     } 
     else 
      ++i; 
} 
    for (size_t i = 0; i < ia.size(); ++i) 
     std::cout << '[' << i << "] " << ia[i] << '\n'; 
} 

看到它http://ideone.com/JJ6CE6

也就是說,對於某些數據類型,ia[i] = ia.back();將比swap更快 - 對於其他數據類型更慢(如果它們使用並受益於C++ 11風格的「移動」)。如果i == size() - 1(至少檢查數組元素類型是否安全支持),您可能還想跳過任何自交換/分配。

+0

速度在這裏完全沒有意義,在這種情況下更喜歡交換將是一個完美的例子,恕我直言,如果我有另一種選擇,哪一個更好的代碼可讀性。 – Paranaix

+0

@Paranaix:當然歡迎你的意見,但是O(N^2)與O(N)在我的意義上並不是「完全沒有意義」:至少這是你應該注意的事情,因爲你是編寫代碼,而不管它是否影響你的選擇。 –