C++ Boost或C+中是否有容器+;11哪个作为队列但具有唯一元素?
我正在寻找一个像C++ Boost或C+中是否有容器+;11哪个作为队列但具有唯一元素?,c++,boost,c++11,C++,Boost,C++11,我正在寻找一个像std::queue这样的容器,它将在末尾添加元素(例如,一个带有id类型uint)的自定义类),但前提是该对象不在容器中 只有当id相等时,类的两个元素才被视为相等(我重载了运算符==) C++11或Boost中是否存在这样的容器?这称为带合并的队列。天真的实现是使用如下内容: std::set<your_key_t> unique; std::queue<your_data_t> q; void enqueue(your_data_t x) {
std::queue
这样的容器,它将在末尾添加元素(例如,一个带有id
类型uint
)的自定义类),但前提是该对象不在容器中
只有当id
相等时,类的两个元素才被视为相等(我重载了运算符==
)
C++11或Boost中是否存在这样的容器?这称为带合并的队列。天真的实现是使用如下内容:
std::set<your_key_t> unique;
std::queue<your_data_t> q;
void enqueue(your_data_t x) {
if (unique.insert(x.key).second) {
q.push(std::move(x));
}
}
your_data_t dequeue(your_data_t dflt) {
if (!q.empty()) {
your_data_t x = std::move(q.front()); q.pop();
unique.erase(q.front().key);
return x;
}
else return dflt;
}
std::设置唯一性;
std::队列q;
无效排队(您的数据){
if(唯一。插入(x键)。秒){
q、 推(std::move(x));
}
}
您的\u数据\u t出列(您的\u数据\u t dflt){
如果(!q.empty()){
您的_data_t x=std::move(q.front());q.pop();
唯一。擦除(q.front().key);
返回x;
}
否则返回dflt;
}
一个不太简单的实现可能是以某种非平凡的方式(比如覆盖)将传入数据与队列中的数据合并,而不是仅仅删除更新。除了,下面是另一个示例,说明如何组合*并使用要查找的属性形成容器
template <typename T>
class QueueUnique {
public:
void push(T t) {
if (set_.insert(t).second) {
queue_.push(std::move(t));
}
}
T& front() { return queue_.front(); }
T& back() { return queue_.back(); }
typename std::set<T>::size_type size() { return set_.size(); }
/* More functions */
private:
std::set<T> set_;
std::queue<T> queue_;
};
模板
类队列唯一{
公众:
无效推力(T){
if(设置插入(t).second){
队列推送(std::move(t));
}
}
T&front(){返回队列u.front();}
T&back(){返回队列u.back();}
typename std::set::size_type size(){return set_u.size();}
/*更多功能*/
私人:
std::set_u2;;
std::队列;
};
像这样使用:
QueueUnique<int> q;
q.push(1);
q.push(1);
q.push(2);
q.push(3);
q.push(1);
std::cout << "Size: " << q.size() << std::endl; // Size: 3
std::cout << "Front: " << q.front() << std::endl; // Front: 1
std::cout << "Back: " << q.back() << std::endl; // Back: 3
q;
q、 推(1);
q、 推(1);
q、 推(2);
q、 推(3);
q、 推(1);
这主意不错,+1。但由于OP要求使用C++11,无序集
几乎肯定会更好,因为它有O(1)插入、搜索和删除。另外,set
要求OP define操作符将其更改为使用unordered\u set
是微不足道的,而且这个想法已经被清楚地解释了。@SchighSchagh-当你盲目地建议unordered\u map
具有不确定的访问延迟时,当你声称它是O(1)时,你应该非常小心
当它实际上是O(N)
,并且忘记了定义了相应的std::hash
(或自定义)的键以便与无序映射一起使用时
两个备注:(1)它是唯一的.erase()
(而不是唯一的.remove()
)。(2) 为了获得强大的异常安全保证(前提是您的\u data\u t
移动构造函数(如果存在)允许),交换行unique.erase(q.front().key)
和您的_data_t x=std::move(q.front())代码>@bobah这不是一个盲目的建议。是的,最坏的情况是O(N),但平均情况是O(1),具有良好的散列。在OP的例子中,他使用uint
作为键,因此std::hash
就可以了。虽然肯定会有一些病理情况下,无序集
的表现比集
差,但这些情况在实践中极为罕见和/或人为造成的。顺便说一句,set
也有不确定的访问延迟(一半节点位于深度log(n)
,另一半不在;树可能需要重新平衡,等等)。为什么需要push()
的参数作为右值引用