在除钥匙之外的东西上订购容器

时间:2015-10-06 10:32:39

标签: c++ c++11 containers

我目前正在尝试实施A *算法,但我遇到了问题:

我想保留一组不同的对象,由哈希标识(我使用boost::hash和系列,但可以使用其他任何东西)并按公共int值排序,这些对象的成员

目标是能够根据O(1)中的int值检索较小的对象,并以最有效的方式保证唯一性(哈希似乎是实现这一目标的好方法,但我对替代方案持开放态度)。如果满足这两个条件,我不需要迭代容器。

是否有任何已经存在的实现可以满足这些规范?我错误地假设了吗?我应该扩展任何现有容器吗?

编辑:

显然不清楚什么&#34;较小的基于int值&#34;手段。我的意思是我的对象有一个公共属性(比如score)。对于两个对象aba < b当且仅当a.score < b.score

我希望ab位于score排序的容器中。如果我尝试使用c插入c.hash == a.hash,我希望插入失败。

3 个答案:

答案 0 :(得分:1)

虽然std::priority_queue是适配器,但其Container模板参数必须满足SequenceContainer,因此您无法构建由std::set支持的版本。

看起来您最好的选择是维护集合和优先级队列,并使用前者来控制插入后者。将它封装到容器概念类中可能是一个好主意,但如果您对它的使用非常本地化,那么您可能会使用几种方法。

答案 1 :(得分:0)

您可以使用stl类型priority_queue。如果你的元素是整数,那么你可以这样做:

priority_queue<int> q;

优先级队列在内部使用堆实现,这是一个完整的二叉树,其根始终是该集的最小元素。因此,您可以通过调用top()来咨询O(1)。

但是,在算法进度时,您需要使用pop()提取项目。由于是一个二叉树,提取需要O(log N),它不是O(1),但是是一个非常好的时间,并且与预期时间形成对比,这是不完美的情况。哈希表 。

我不知道在O(1)中维护集合和提取最小值的方法。

答案 2 :(得分:0)

使用自定义比较器和std :: set:

#include <set>
#include <string>

struct Object
{
  int value;
  long hash;

  std::string data;

  Object(int value, std::string  data) :
    value(value), data(data)
  {

  }

  bool operator<(const Object& other) const
  {
    return data < other.data;
  }

};

struct ObjComp1
{

  bool operator()(const Object& lhs, const Object& rhs) const
  {
    return lhs.value < rhs.value;
  }

};

struct ObjComp2
{

  bool operator()(const Object& lhs, const Object& rhs) const
  {
    if (lhs.value != rhs.value)
    {
      return lhs.value < rhs.value;
    }

    return lhs < rhs;
  }

};

int main()
{

  Object o1(5, "a");
  Object o2(1, "b");
  Object o3(1, "c");
  Object o4(1, "c");

  std::set<Object, ObjComp1> set;
  set.insert(o1);
  set.insert(o2);
  set.insert(o3);
  set.insert(o4);

  std::set<Object, ObjComp2> set2;
  set2.insert(o1);
  set2.insert(o2);
  set2.insert(o3);
  set2.insert(o4);

    return 0;
}

第一个变体将允许您只插入o1和o2,第二个变体将允许您插入o1,o2和o3,因为它不是很清楚你需要哪一个。唯一的缺点是你需要编写自己的运算符&lt;对象类型。

或者,如果您不想创建自定义运算符&lt;对于你的数据类型,你可以包装一个std :: map&gt;但这不太直白