【问题标题】:C++ how to mix a map with a circular buffer?C ++如何将地图与循环缓冲区混合?
【发布时间】:2011-11-01 11:37:01
【问题描述】:

我想知道是否有可能有一个像 boost 循环缓冲区一样工作的地图。这意味着它的大小是有限的,当它达到其有限的大小时,它将开始覆盖第一个插入的元素。我也希望能够通过这样的缓冲区和find or create[name] 进行搜索。是否可以创建这样的东西以及如何做?

【问题讨论】:

  • 当您说map 时,您是否想要 std::map(已排序元素集)或其他功能
  • 按地图我的意思是std::map api,一个由第一个元素对索引的数组.. 可以说在其中有pair<stringed_index, some_class_of_mine> 我会调用my_map[stringed_index_id] 并得到some_class_of_mine_id 或为我创建了一个new

标签: c++ dictionary boost circular-buffer


【解决方案1】:

您需要的是 LRU(最近最少使用)地图或 LRA(最近最少添加)地图,具体取决于您的需要。

实现已经存在。

【讨论】:

【解决方案2】:

嗯,我不认为 boost 中的结构是开箱即用的(但可能存在于其他地方),所以你应该创建它。不过,我不建议使用operator[](),至少因为它在std::map 中实现,因为这可能难以跟踪添加到地图中的元素(例如,使用带有值的operator[]() 会添加空值到地图),并使用更明确的 get 和 put 操作来添加和检索地图的元素。

至于最简单的实现,我会使用实际的map 作为存储,deque 用于存储添加的元素(未测试):

template <typename K, typename V>
struct BoundedSpaceMap
{
    typedef std::map<K,V> map_t;
    typedef std::deque<K> deque_t;

    // ...
    typedef value_type map_t::value_type;
    // Reuse map's iterators
    typedef iterator map_t::iterator;

    // ...
    iterator begin() { return map_.begin(); }

    // put
    void put ( K k, V v)
    { map_.insert(std::make_pair(k,v));
      deque_.push_back(k);
      _ensure();  // ensure the size of the map, and remove the last element
    }

     // ...

private:
     map_t map_;
     deque_t deque_;

     void _ensure() { 
       if (deque_size() > LIMIT) { 
         map_.erase(deque_.front()); deque_.pop_front();
       }
     }
};

【讨论】:

    【解决方案3】:

    并不是真正的“循环缓冲区”,因为这对地图没有多大意义,但我们可以使用一个简单的数组,而不需要任何额外的链表或任何东西。

    这被称为closed hashing - 维基文章很好地总结了它。双散列是最常用的,因为它避免了聚类(这会导致性能下降),但也有其自身的问题(局部性)。

    编辑:由于您想要一个特定的实现,我不认为 boost 有一个,但在另一篇关于封闭散列的 SO 帖子中提到了 thisthis..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多