【问题标题】:Searching in std::set without iterator C++在没有迭代器 C++ 的 std::set 中搜索
【发布时间】:2012-11-09 13:13:27
【问题描述】:

我有 std::set,其中包含 int 值。现在我使用迭代器来找出set是否包含value

但是我的应用程序使用这种搜索非常频繁并且使用迭代器搜索太慢了,我可以这样做吗:

std::set<int> fdsockets;

void myfunc(int fd)
{
    if(fdsockets[fd] != fdsockets.end())
    {
            // my code
    }
}

但是使用 G++ 编译时出现错误

'fdsockets[fd]'中的'operator[]'不匹配

也许我可以用一些东西代替std::set

谢谢!

【问题讨论】:

  • 之所以更喜欢find() 而不是循环而不是集合的原因是find() 是一个O(log(N)) 算法。循环比 O(N) 更糟糕(我怀疑它是 O(N*log(N)) 算法),因为 operator++() 对于那些关联容器来说相当复杂。
  • std::set 有一个 find() 方法,即 O(log(n))

标签: c++ iterator stdset


【解决方案1】:

std::unorered_set 或带二分查找的有序vector 对于简单的成员资格测试更有效。如果整数的最大值很低,则可以使用查找表。

【讨论】:

  • 只有在很少从向量中添加或删除元素的情况下,使用二进制搜索的已排序 vector 才会更有效。每次插入或删除都需要 nlgn 时间。但搜索会快得多。
  • 你是对的。二进制搜索或静态表仅用于静态数据。
  • @Yakk 这还不确定。这也取决于数据集的大小。而复制int 是非常便宜的操作;插入和删除,即使是在一个中等大的数据集中,使用排序向量可能比使用std::set便宜:你可以以一次分配的价格复制大量数据(并且找到插入位置也更便宜)。
【解决方案2】:

听起来你想要set::find()

if( fdsockets.find(fd) != fdsockets.end() )
{
      // my code
}

【讨论】:

    【解决方案3】:

    std::set 中没有 operator[]。

    你可能是说

    if(fdsockets.find(fd) != fdsockets.end())
    

    【讨论】:

      【解决方案4】:

      如果您不需要 set::find 返回的迭代器(您只是在测试存在,实际上并不打算访问 fdsocket),这里有一个替代方案:

      if(fdsockets.count(fd))
      {
              // my code
      }
      

      【讨论】:

        猜你喜欢
        • 2015-06-11
        • 1970-01-01
        • 1970-01-01
        • 2012-09-13
        • 2012-10-03
        • 1970-01-01
        • 1970-01-01
        • 2010-12-10
        • 1970-01-01
        相关资源
        最近更新 更多