【问题标题】:container with both unique elements and access by index具有唯一元素和按索引访问的容器
【发布时间】:2014-10-07 07:02:27
【问题描述】:

似乎不清楚我到底想要什么,所以我改写了这个问题

有些容器的每个元素都是唯一的(例如setmap),但是对于那些我无法通过索引访问元素(例如从容器中获取单个对象),如下所示:

std::set<Object> set {obj1, obj2};
Object o = set[0]; // does not work

因此,要拥有一个仅存储唯一元素的具有通过索引功能(例如vector)访问的容器,我必须手动确保容器中的所有元素都是唯一的,如下所示:

std::vector<Object> vec { ... }; // vector with some objects
// adding an object
if (std::count(vec.begin(), vec.end(), obj) == 0) {
    vec.push_back(obj);
} else {
    std::cout << "object already in container!\n";
}

每次添加对象时肯定遍历整个容器可能会很昂贵,所以我想知道是否有更好的解决方案。

【问题讨论】:

  • 提取?你的意思是删除、阅读还是什么?
  • @Adrian May:我的意思是,获取一个对象并以其他方式使用它。
  • 你也可以用套装做到这一点。
  • @Jagannath:但它没有 at() 函数或使用 [] 运算符?
  • 我还是不明白你的意思。如果你用一个名为 Fantasy 的理想集合编写你的幻想代码,然后我们可能会知道你想要做什么

标签: c++ stl containers


【解决方案1】:

您可以创建自己的容器。比如:

#include <cassert>
#include <iostream>
#include <set>
#include <vector>

template<class OBJ>
class idx_set
{
public:
  // ...

 bool insert(const OBJ &o)
 {
   if (set_.find(o) == set_.end())
   {
     set_.insert(o);
     vect_.push_back(o);
     return true;
   }

   return false;
 }

 const OBJ &operator[](unsigned i) const { return vect_[i]; }

 // ...

private:
  std::set<OBJ> set_;
  std::vector<OBJ> vect_;
};

int main()
{
  idx_set<int> im;

  assert(im.insert(10));
  assert(im.insert(12));
  assert(!im.insert(10));

  std::cout << im[0] << im[1] << std::endl;

  return 0;
}
  • 添加新元素(O(logN) 复杂度)不会改变现有元素的索引。

    std::set 更改为std::unordered_set 可以降低插入复杂度

  • 通过索引访问元素很快(O(1) 复杂度)。

    请注意,基于std::map&lt;unsigned, OBJ&gt; 的解决方案在这方面会更简单但速度较慢。

  • 编码并不太复杂

当然,你是在牺牲内存来换取速度。

【讨论】:

  • 是的,这实际上就是我现在所做的,我有一个向量,我在将元素添加到向量之前检查它是否已经在其中。虽然在你的例子中我不需要一个集合。
  • 检查无序向量中是否存在元素比较慢:O(N) vs O(log N)(或使用std:unordered_set的O(1))。
  • 啊,好吧,这很聪明! :)
猜你喜欢
  • 1970-01-01
  • 2016-12-11
  • 2017-04-23
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
  • 2019-06-26
相关资源
最近更新 更多