从向量中删除元素

发布于 2024-12-11 06:13:27 字数 752 浏览 0 评论 0原文

在 C++ 中,如何从向量中删除元素?

  1. 从原来的位置删除它,即让向量调整大小
  2. 将要删除的元素与最后一个元素交换可以使用 st 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;
}

In C++, how can I delete an element from a vector?

  1. Delete it right from where it is, i.e. let the vector resize
  2. 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...)

For (1), I've tried the following, but I'm not quite sure if it does what it is supposed to do (remove the item passed to removeItem() ), and it doesn't seem very elegant:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

羁绊已千年 2024-12-18 06:13:27

标准的 remove+erase 习惯用法按值删除元素:

#include <vector>
#include <algorithm>

std::vector<int> v;
v.erase(std::remove(v.begin(), v.end(), 12), v.end());

remove 对元素重新排序,以便所有擦除对象都位于末尾,并返回一个指向擦除范围开头的迭代器,而erase实际上是从容器中删除元素。

这与使用像 vector 这样的连续存储容器一样高效,特别是如果您有多个具有相同值的元素,并且一次清洗就将其全部删除。

The standard remove+erase idiom removes elements by value:

#include <vector>
#include <algorithm>

std::vector<int> v;
v.erase(std::remove(v.begin(), v.end(), 12), v.end());

remove reorders the elements so that all the erasees are at the end and returns an iterator to the beginning of the erasee range, and erase actually removes the elements from the container.

This is as efficient as you can get with a contiguous-storage container like vector, especially if you have multiple elements of the same value that all get erased in one wash.

蘑菇王子 2024-12-18 06:13:27
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 呢?

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

Though, if the order doesn't matter, why not just use a std::set?

ぃ双果 2024-12-18 06:13:27

从原来的位置删除它,即让向量调整大小

这就是erase 的作用。

可以使用最后一个元素 st pop_back() 交换要删除的元素(我希望这不会涉及复制周围的所有内容......)

这就是 remove 的作用,只不过它保留了顺序其余对象,因此它确实涉及复制周围的所有内容。

您所做的可以写为:

items.erase(
    std::remove(
        items.begin(), items.end()
      , item
    )
  , items.end()
);

与您的代码的区别在于,这实际上会删除值为 item所有项目,而不仅仅是第一个。

Delete it right from where it is, i.e. let the vector resize

That's what erase does.

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...)

That's what remove does, except that it preserves the order of the remaining objects so it does involve copying everything around.

What you've done could be written as:

items.erase(
    std::remove(
        items.begin(), items.end()
      , item
    )
  , items.end()
);

The difference with your code being that this will actually remove all items valued item, instead of just the first one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文