【问题标题】:check if a std::vector contains a certain object? [duplicate]检查 std::vector 是否包含某个对象? [复制]
【发布时间】:2011-03-27 22:09:54
【问题描述】:

<algorithm> 中有什么东西可以让你检查一个 std:: 容器是否包含一些东西吗?或者,一种制作方法,例如:

if(a.x == b.x && a.y == b.y)
return true;

return false;

这只能通过 std::map 来完成,因为它使用了密钥?

谢谢

【问题讨论】:

  • 如果它包含特定的东西,或者只是它不是空的?
  • 您使用的是哪个 C++ 参考?并且标题被称为<algorithm> - 注意没有.h。
  • 特定的东西,例如自定义结构。
  • 如果容器包含自定义结构,那么您需要实现operator== 来比较它们;那么std::find 就可以了。
  • 喜欢duplicate中的回答,我觉得最优雅的还是用boost::algorithm::any_of_equal

标签: c++ vector


【解决方案1】:

检查v是否包含元素x

#include <algorithm>

if(std::find(v.begin(), v.end(), x) != v.end()) {
    /* v contains x */
} else {
    /* v does not contain x */
}

检查v 是否包含元素(非空):

if(!v.empty()){
    /* v is non-empty */
} else {
    /* v is empty */
}

【讨论】:

  • 如果 x 是 v 中的最后一个元素怎么办?
  • 大卫,end() 指向最后一个元素之后的一个,所以一切正常。
  • 在尝试确定向量中是否包含双精度时,这是否考虑了数值容差?
  • @NicholasHamilton:不,它使用operator==。如果您需要考虑数值容差,请使用 std::find_if 并提供合适的谓词。
  • @DarnocEloc:没有。
【解决方案2】:

如果搜索元素很重要,我建议使用std::set 而不是std::vector。使用这个:

std::find(vec.begin(), vec.end(), x) 在 O(n) 时间内运行,但 std::set 有自己的 find() 成员(即myset.find(x)),它在 O(log n) 时间内运行 - 这对于大量元素

std::set 还保证所有添加的元素都是唯一的,这样您就不必像if not contained then push_back()... 那样做任何事情。

【讨论】:

  • 太棒了!!!我正在写一个词法分析器。集合将比向量好得多。 set 是否有像 map 这样的 count 方法?我还希望能够获取集合中元素的索引。
  • 很好的信息!感谢您回答直截了当的问题并提供了额外的解决方案。
  • 这是个坏建议。如果性能很重要,请配置文件。无法保证复杂性分析对您的具体问题有任何意义。
  • 这取决于元素的数量。 std::set 的查找特性非常适合以数据局部性为代价的具有大量元素的容器。您必须执行性能分析(例如分析)来决定多高才足以从矢量数据结构切换到集合数据结构。
  • @Segmentation O(n) 表示法与最坏情况无关。 AFAIK,set 根本不像vector。大多数set 实现使用红黑树,这有很大的开销。我不知道标题增加开销是什么意思。开销通常是指运行时开销。 set 的最佳用例是“我感觉很懒,不想考虑它”和“我需要尽快完成这件事”。如果您关心性能,则需要进行概要分析。 unordered_set 可能值得一试。
【解决方案3】:

查看问题:How to find an item in a std::vector?

如果默认的operator==() 不足以进行“深度”相等性测试,您还需要确保为您的对象实现了合适的operator==()

【讨论】:

  • 我通常不会为我的班级实现自定义operator==(),以便能够使用一次或两次std::find()。如果将覆盖添加到类的公共接口中确实有意义,我只会这样做。需要能够使用std::find() 并不能证明这一点。此外,如果您需要执行两次std::find() 但需要以不同的方式比较您的对象怎么办?喜欢在不同的财产上?
  • 如果您担心实现operator==,那么我建议您使用std::find_if,那么您可以为您的不同标准案例提供可重复使用的谓词
猜你喜欢
  • 2011-09-10
  • 1970-01-01
  • 2016-10-16
  • 1970-01-01
  • 2011-04-02
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多