【问题标题】:What is a C++ container with a "contains" operation?什么是具有“包含”操作的 C++ 容器?
【发布时间】:2011-05-31 23:47:08
【问题描述】:

我想用我插入整数的结构,然后可以问

if (container.contains(3)) { /**/ }

一定有这样的东西。

【问题讨论】:

    标签: c++ insert integer containers contains


    【解决方案1】:

    您可以使用std::vector

    std::vector<int> myVec;
    myVec.push_back(3);
    if (std::find(myVec.begin(), myVec.end(), 3) != myVec.end())
    {
        // do your stuff
    }
    

    你甚至可以做一个小辅助函数:

    template <class T>
    bool contains(const std::vector<T> &vec, const T &value)
    {
        return std::find(vec.begin(), vec.end(), value) != vec.end();
    }
    

    你会如何使用它:

    if (contains(myVec, 3)) { /*...*/ }
    

    【讨论】:

    • @Nemo:OP 从未要求快速执行方法,而只是要求一种工作方法。我为一般问题提供了一般解决方案。如果 OP 要求速度很重要的特定问题,那么其他解决方案会更好。立即选择std::set 只是为了保存线性时间搜索意味着其他设计后果,我认为这是过早的优化(实际上搜索甚至不会处于性能瓶颈中)。过早的优化是万恶之源。 IMO,对问题的不同解决方案不值得投反对票。
    • @Nemo:正确的线性时间解决方案很好,除非测量证明它是一个重要的瓶颈。
    • 如果由于某种原因(例如,您想保留插入顺序)不能使用排序列表或哈希表,则最好采用线性时间。
    • 我们都应该知道的:内存中线性集合的线性迭代(如果是同质的则作为向量)(如果重复)快如闪电!保持阴影靠近!
    【解决方案2】:

    简单算法:

    template <typename Container>
    bool contains(Container const& c, typename Container::const_reference v) {
      return std::find(c.begin(), c.end(), v) != c.end();
    }
    

    您可以对其进行自定义,以便在某些已知容器上进行更有效的搜索:

    template <typename Key, typename Cmp, typename Alloc>
    bool contains(std::set<Key,Cmp,Alloc> const& s, Key const& k) {
      return s.find(k) != s.end();
    }
    
    template <typename Key, typename Value, typename Cmp, typename Alloc>
    bool contains(std::map<Key,Value,Cmp,Alloc> const& m, Key const& k) {
      return m.find(k) != m.end();
    }
    

    通过这种方式,您可以获得对任何容器类型执行搜索的单一算法,并且在特殊情况下可以在订购的容器上更快。

    【讨论】:

    • 现在这就是我想要的。谢谢
    【解决方案3】:

    find 在未排序的向量上是 O(n)。

    std::set 支持 O(log n) 插入和查找,是一个不错的选择。

    std::tr1::unordered_set 提供了类似的接口,但支持近乎恒定的时间查找。如果你有 TR1(或 C++0x)并且不需要按顺序枚举元素,这是最好的选择。

    【讨论】:

    • 对于小的 n,未排序的向量非常好,甚至可能更快。
    【解决方案4】:

    您想要的是算法库中的 find_first_of 方法。 (或二进制搜索,或任何类似的东西)

    http://www.cplusplus.com/reference/algorithm/find_first_of/

    【讨论】:

    • std::find_first_of 在更大的序列中搜索子序列,但 'contains(3)' 只有一个标量,没有开始/结束范围。所以 std::find 更适合这里。
    【解决方案5】:

    如果你想使用 C++ 标准容器,由于它的设计,容器本身不一定有“包含”,但你总是可以使用 find 算法。

    你应该根据你的数据集的特点和访问“工作量”来选择你的容器。

    有关 C++ 标准库中的容器和算法的良好参考,请查看 http://www.cplusplus.com

    Containers, Algorithms

    如果您的数据看起来是由独特的项目组成的,并且您希望为其关联一个值,那么地图容器可能会为您提供很好的服务。如果你只关心“会员”,那么 set 是更好的选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-22
      • 1970-01-01
      • 1970-01-01
      • 2013-01-11
      • 2011-01-09
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多