2016-03-03 49 views
-1
void foodAgainstCreatures(vector<creature>& displayCreatures, vector<Food>& displayFood) 
{ 
bool hungry = true; 
int differenceInX = 0; 
int differenceInY = 0; 
for (unsigned int j = 0; j < displayCreatures.size(); j++) 
{ 
    hungry = true; 
    for (unsigned int i = 0; i < displayFood.size(); i++) 
    { 
     differenceInX = displayCreatures[j].getXValue() - displayFood[i].getXValue(); 
     differenceInY = displayCreatures[j].getYValue() - displayFood[i].getYValue(); 
     if ((differenceInX <= 5 && differenceInX >= -5) && (differenceInY <= 5 && differenceInY >= -5)) 
     { 
      displayCreatures[j].addToEnergy(3); 
      displayFood.erase(displayFood.begin() + i); 
      hungry = false; 

     } 
     else 
     { 
      if (displayCreatures[j].getEnergy() == 0) 
      { 
       displayCreatures.erase(displayCreatures.begin() + j); 
      } 
     } 

    } 
    if (hungry == true) 
    { 
     displayCreatures[j].addToEnergy(-1); 
    } 
} 
} 

//一次“生物”,“吃”是“食品”,它获得的“能量”的正常工作有什么我需要是再帮消除已经从载体中“吃掉”的“食物”。我可以在循环内做到这一点吗?怎样才能从我的矢量删除元素,而在for循环C++

+3

是一个天使,并使用std :: size_t而不是unsigned int作为循环计数器。 – Bathsheba

+0

哈哈我会做谢谢你 – KPullet

+0

你的问题描述是缺乏。无论如何,将你想要保留的元素复制到一个新的矢量并与前一个交换相比更容易。如果您不认为移除元素会改变其他元素,以及对您的循环有什么影响。另外,请查看右边相关问题的列表,你的这些并不新鲜。 –

回答

0

你有几个选项。
1.以相反的顺序遍历矢量,这种方式删除不会影响你要访问的元素。
2.使用更合适的收集,如列表。
3.如果顺序不重要,可以使用“快速删除”,只需将当前项目替换为最后一项,减少当前索引和矢量大小。

0

是的,您可以删除循环中的项目。由于您使用索引来访问这些项目,因此您必须确保这些索引是有效的。

std::vector<int> container = {...}; 
for (std::size_t i = 0; i < container.size(); ++i) { 
    if (shouldRemove(container[i]) { 
     container.erase(container.begin() + i); 
     --i; // We don't want to miss the next item 
     continue; 
    } 
} 

但有时你可能需要使用迭代器。当你使用range-based for loops时,你也在使用迭代器。这样的事情就不会是有效的:

std::vector<mystruct_t> container = {...}; 
for (mystruct_t &item : container) { 
    if (item.please_remove_an_item) { 
     container.erase(container.begin() + item.the_item_to_be_removed); 
    } 
} 

你能做什么,而使用迭代器依赖于容器的类型。你可以找到一些关于它的规则here。在使用std::vector时,删除条目后不允许使用迭代器。由于erease返回迭代器的下一个elelemt,就可以做这样的事情:

auto it = container.begin(); 
while (it != container.end()) { 
    if (shouldRemove(*it)) { 
     it = container.erase(it) 
     continue; 
    } 
    ++it; 
} 
0

你不应该被索引迭代和同时取出。正确的方法是通过迭代器擦除。根据周围的代码,你可以水木清华这样的:

for (auto it = displayCreatures.begin(); it != displayCreatures.end();) { 

    if (need_to_erase(it)) { 
     it = container.erase(it) 
     continue; 
    } 

    ... 
    ++it; 
} 

UPD:我编辑,因为在代码错字的, - .erase移动迭代器(也就是全部的想法),在这种情况下++是不需要

+0

使用此代码删除另一个后,您将跳过一个条目。如果您删除项目* 0 *,您将永远不会看现在位置* 0 *中的项目* 1 *。 – JojOatXGME

+0

,这将无法正常工作,您需要擦除项目或增加迭代器,导致擦除返回下一个有效的迭代器。 – Sergi0

+0

哎唷,是的,没错。抱歉。没有仔细检查就写了。确实如果.erase,不需要++。 – rezdm