在for循环C ++中,如何从向量中删除元素

时间:2016-03-03 15:24:28

标签: c++ loops for-loop visual-studio-2013 vector

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);
    }
}
}

//一次&#34;生物&#34; &#34;吃&#34; a&#34;食物&#34;它获得了能源&#34;哪个工作正常我需要帮助然后删除&#34;食物&#34;已经被吃掉了#34;从矢量。我可以在循环内做到这一点吗?

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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;
}

答案 2 :(得分:0)

您不应该按索引进行迭代并同时删除。正确的方法是通过迭代器擦除。根据周围的代码,您可以像下面那样:

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

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

    ...
    ++it;
}
更新:我编辑了,因为代码中出现了拼写错误 - .erase移动迭代器(这就是整个想法),在这种情况下++不需要

相关问题