我有一个包含一组 std::pair
的数据结构。我需要这个数据结构有两个重要的属性:
,作为一名使用 cppreference.com 的 C++ 初学者,我选择了 std::queue> 。 frontierPointsUV{};
其中我有 typedef std::pair; PointUV;
我在下面的附录中包含了 PointUVHash
的实现。
我的问题是,
- 这是满足上述 2 个要求的明智方法吗?
- 如何检查集合成员资格?我已尝试使用
frontierPointsUV.c.contains
来设置成员资格,但出现“没有成员”错误。
- 如何推入和弹出(或插入和擦除)?我尝试在任一容器上调用这些修饰符都没有成功。
附录 - 哈希实现
struct pointUVHash final
{
// This is a safe hashing function for pointUV because we only ever expect it to have 0 or positive ints
// in ranges well under 2**16
int operator()(const PointUV &p) const
{
return int(p.first) + (int(p.second) << 16);
}
};
I have a data structure containing a set of std::pair<int, int>
. There are two important properties I require for this data structure:
- I can check set membership fast.
- FIFO
So as a C++ beginner armed with cppreference.com I went for std::queue<std::unordered_set<PointUV, pointUVHash>> frontierPointsUV{};
where I have typedef std::pair<int, int> PointUV;
and I include the implementation of PointUVHash
in the appendix below.
My questions are
- Is this a sensible way to meet the 2 requirements above?
- How do I check set membership? I've tried
frontierPointsUV.c.contains
for set membership but I get "has no member" errors.
- How to I push and pop (or insert and erase)? I've been unsuccessful with trying to call these modifiers on either of the containers.
Appendix - Hash implementation
struct pointUVHash final
{
// This is a safe hashing function for pointUV because we only ever expect it to have 0 or positive ints
// in ranges well under 2**16
int operator()(const PointUV &p) const
{
return int(p.first) + (int(p.second) << 16);
}
};
发布评论
评论(1)
队列适配器需要一个有序的容器(例如双端队列或列表)才能工作。在我看来,它也已经过时了,因为它只删除了底层容器的功能,并且没有添加任何实质性内容。
您想要的是两个保持同步的数据结构,例如一个
unordered_set 。 >
和一个deque >
。看看pair
是一个非常简单的类型,这种组合效果最好。如果您开始处理更复杂的类型,您可能希望避免重复的对象和查找,那么将指针存储在其中一个容器中可能是一种选择。不管怎样,这样的事情应该可以解决问题:
我保持函数语义有点接近队列或双端队列提供的功能,例如,如果在空队列上调用
front()
,则会出现未定义的行为。如果您希望队列中有多个相等的键,最简单的方法是将
unordered_set; >
和unordered_map, size_t>
来跟踪队列中有多少个相等的键。像这样的事情:The queue adaptor requires an ordered container such as deque or list to work. In my opinion, it is also obsolete as it only removes functionality from the underlying container and doesn't add anything of substance.
What you want is two data structures that are kept in-sync, e.g. one
unordered_set<pair<int, int> >
and onedeque<pair<int, int> >
. Seeing howpair<int, int>
is a very simple type, this combination works best. If you start handling more complex types where you may want to avoid duplicate objects and lookups, storing pointers in one of the containers may be an option.Anyway, something like this should do the trick:
I've kept the function semantics somewhat close to what queue or deque provide, e.g. undefined behavior if
front()
is called on an empty queue.If you want multiple equal keys in your queue, the easiest way is to replace
unordered_set<pair<int, int> >
withunordered_map<pair<int, int>, size_t>
to keep track of how many equal keys are in the queue. Something like this: