c++ 中 std::vector 的 ArrayList 样式的 indexOf?

发布于 2024-10-04 04:17:21 字数 351 浏览 8 评论 0原文

我从 Java 进入 C++,并且有一个常见的设计情况,其中我有一个元素(非基元),我想从 std::vector 中删除它。

在Java中,我会写这样的东西: arrayList.remove(arrayList.indexOf(myClassInstance));

在 C++ 中,使用 std::vector,最好/最高效/最干净的方法是什么?

我能想到的最好的事情是创建对我正在搜索的实例的引用,然后迭代向量直到找到该引用。本质上,将向量中每个元素的内存地址与引用进行比较,直到获得匹配。

我走在正确的轨道上吗?或者有更好的方法吗? (也许使用不同的 std 容器,到目前为止我只使用了 std::vector 。)

i'm coming into C++ from Java, and have a common design situation in which i have an element (a non-primitive) that i'd like to remove from a std::vector.

in Java, i'd write something like:
arrayList.remove(arrayList.indexOf(myClassInstance));

in C++, with a std::vector, what's the best / most performant / cleanest way of doing this?

the best thing i can think of is to create a reference to the instance i'm searching for, and then iterate through the vector until i find that reference. essentially, to compare the memory address of each element in the vector with the reference until i get a match.

am i on the right track? or is there a better way of doing this? (perhaps using a different std container, i've only used std::vector so far.)

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

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

发布评论

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

评论(3

瑾夏年华 2024-10-11 04:17:21
#include <algorithm>

std::vector<Foo>::iterator it = std::find(vec.begin(), vec.end(), foo_2b_found);
if (it != vec.end()) vec.erase(it);
#include <algorithm>

std::vector<Foo>::iterator it = std::find(vec.begin(), vec.end(), foo_2b_found);
if (it != vec.end()) vec.erase(it);
当梦初醒 2024-10-11 04:17:21

使用 std::find 查找元素并 < a href="http://www.cplusplus.com/reference/stl/vector/erase/" rel="nofollow">vector::erase 将其删除。

std::find 本质上是遍历向量来查找元素,使用简单的向量你无法做得更好(Java 的 ArrayList 的情况也是如此) 。是否应该使用不同的容器取决于您的要求。

Use std::find to find the element and vector::erase to remove it.

std::find essentially iterates through the vector to find the element, and you can't do any better with a simple vector (the same is the case with Java's ArrayList). Whether or not you should use a different container depends on your requirements.

走走停停 2024-10-11 04:17:21

如果您想通过向量线性搜索,那么

seq.erase( std::find( seq.begin(), seq.end(), elt ));

如果您有一个谓词并且想要删除与谓词匹配的所有项目,那么:

seq.erase( std::remove_if( seq.begin(), seq.end(), Pred ), seq.end());

这些方法都不是最有效的方法,因为它们需要线性查找,即使您的元素很早就找到了,擦除的成本很高,因为它必须将所有其他元素移动一个位置以保持它们连续。

使用 std::list 将解决后者:搜索将是线性的,但擦除将是恒定时间。

如果可以将元素存储在使用键查找的关联容器中,那么效率会更高:O(log N) 查找和常数时间删除。

哈希映射可能更好,接近恒定时间查找和删除。

对于您的建议,即通过对象的指针擦除,您可以使用 std::set 作为您的类型 T。然后使用 mySet.erase( pt ); ,其中 pt 是您的指针。当然,您需要管理指针的生命周期,但事实上您知道要从集合中删除哪一个指针,这表明您在其他地方拥有它的副本。

您可以使用 std::set, SharedPtrLess >

您定义 SharedPtrLess 的位置如下:

template< typename T >
struct SharedPtrLess
{
   bool operator()( boost::shared_ptr<T> left, boost::shared_ptr<T> right ) const
   {
     return std::less<T>()( left.get(), right.get());
   }
};

If you want to search linearly through the vector then

seq.erase( std::find( seq.begin(), seq.end(), elt ));

If you have a predicate and want to remove all items that match the predicate then:

seq.erase( std::remove_if( seq.begin(), seq.end(), Pred ), seq.end());

None of these methods are the most performant way because they require linear lookup and even if your element is found early on, the erase is expensive because it has to move all the other elements by a position to keep them contiguous.

Using std::list would address the latter of these: the search would be linear but the erase would be constant time.

If it is possible to store your elements in an associative container that uses a key lookup then that would be more efficient: O(log N) lookup and constant time removal.

A hash map may be even better, close to constant time lookup and removal.

For what you are suggesting, i.e. erasing by the pointer of the object, you could use std::set for your type T. Then use mySet.erase( pt ); where pt is your pointer. You need to manage the lifetime of your pointers, of course, but the fact you know which one to erase from your collection suggests you have a copy of it elsewhere.

You might use std::set, SharedPtrLess >

where you define SharedPtrLess as follows:

template< typename T >
struct SharedPtrLess
{
   bool operator()( boost::shared_ptr<T> left, boost::shared_ptr<T> right ) const
   {
     return std::less<T>()( left.get(), right.get());
   }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文