是否可以按值删除队列元素?

时间:2011-10-09 17:30:43

标签: c++ stl queue std

我想从队列中删除具有特定值的元素。怎么办这样的事情? (我正在尝试创建地图和队列的并发混合,目前我尝试在this answer上实现)

所以我目前有这样的代码:

#ifndef CONCURRENT_QUEUED_MAP_H
#define CONCURRENT_QUEUED_MAP_H

#include <map>
#include <deque>
#include <boost/thread.hpp>
#include <boost/thread/locks.hpp>

template <class map_t_1, class map_t_2>
class concurrent_queued_map
{
private:
    std::map<map_t_1, map_t_2> _ds;
    std::deque<map_t_1> _queue;
    mutable boost::mutex mut_;
public:
    concurrent_queued_map() {}

    map_t_2 get(map_t_1 key) {
        boost::mutex::scoped_lock lock(mut_);
        return _ds[key];
    }

    map_t_1 put(map_t_1 key, map_t_2 value) {
        boost::mutex::scoped_lock lock(mut_);
        _ds.insert(std::pair<map_t_1, map_t_2>(key,value));
        _queue.push_back(key);
        return key;
    }

    map_t_2 get_last(map_t_1 key) {
        boost::mutex::scoped_lock lock(mut_);
        const map_t_1 k = _queue.front();
        return _ds[k];
    }

    void remove_last(map_t_1 key) {
        boost::mutex::scoped_lock lock(mut_);
        const map_t_1 k = _queue.front();
        _ds.erase(k);
        _queue.pop_front();
    }

    void remove(map_t_1 key) {
        boost::mutex::scoped_lock lock(mut_);
        _queue.erase(std::remove(_queue.begin(), _queue.end(), key), _queue.end());
        _ds.erase(k);
    }

    int size() {
        boost::mutex::scoped_lock lock(mut_);
        return _ds.size();
    }

};

#endif // CONCURRENT_QUEUED_MAP_H

那我该怎么办?如何按值从队列中删除?或者thare是任何类似STL或Boost组件的队列?这意味着它会.front()pop_front();push_back(key);并且还支持按值搜索和删除?

2 个答案:

答案 0 :(得分:18)

deque是一个序列容器,因此您只能通过 value 删除元素,最好使用删除/删除习惯用法:

std::deque<T> q;
T val;

q.erase(std::remove(q.begin(), q.end(), val), q.end());

如果您正在使用std::queue适配器,那么您根本无法执行此操作,因为适配器仅公开front / back接口,并非用于迭代或查找语义

如果您选择将您的队列实现为std::list,请改用成员函数remove()

答案 1 :(得分:2)

Dointg就是这样 - 同时队列和地图都消除了使用它们的优点,并且保留了两者的缺点(至少在性能方面)。我只想使用deque<std::pair<map_t_1, map_t_2> >来表示地图和双端队列。然后地图查找或编辑需要查看整个双端队列,因此效率不高。

更有效的解决方案将更难以实现,因为您正在尝试应对两种不同的索引方案 - 通过键(映射)和索引(通过排序自然od deque所需)。为了有效地做到这一点,我建议使用自己实现的双链表(作为队列),其中包含到linked_list条目的键映射。双链表项还包含在前置/附加队列时在地图中查找的键。