从矢量中删除元素擦除多个(C ++)

时间:2014-03-04 22:30:56

标签: c++ vector

我一直在构建一个小型的Roguelike ASCII游戏,它使用控制台来构建我对C ++的有限知识。我设置了它,所以当玩家对象的坐标与项目(存储在矢量中)相同时,它会移除该项目并将10添加到玩家的HP。

该计划从房间内的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");
        }
}

我还在试图弄清楚向量,所以如果有人能告诉我我做错了什么,我会非常感激。 :)

1 个答案:

答案 0 :(得分: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(至少检查数组元素类型是否安全支持),您可能还想跳过任何自交换/赋值。