如何删除作为地图值的项目

时间:2013-10-17 11:59:07

标签: c++ std

我有这样的地图:

std::map<unsigned,(string,timestamp)> themap.

但我需要通过仅保留地图中最高的1000个时间戳来管理地图的大小。我想知道处理这个问题的最有效方法是什么?

我应该以某种方式将上面的地图复制到

std::map<timestamp,(string,unsigned)> - erase elements not in top 1000, then massage this map back into original?

还是其他方式?

这是我的代码。

/* map of callid (a number) to a carid (a hex string) and a timestamp (just using unsigned here)
   The map will grow through time and potentially grow to some massive amount which would use up all 
   computer memory.  So max sixe of map can be kept to 1000 (safe to do so).  Want to remove items 
   based on timestamp
*/
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <map>


typedef unsigned callid;
typedef unsigned timestamp;
typedef std::string carid;
typedef std::pair<carid,timestamp> caridtime;
typedef std::map<callid,caridtime> callid2caridmap;

int main() {

   //map of callid -> (carid,timestamp)
   callid2caridmap cmap;

   //test data below
   const std::string startstring("4559023584c8");
   std::vector<carid> caridvec;
   caridvec.reserve(1000);
   for(int i = 1; i < 2001; ++i) {
      char buff[20] = {0};
      sprintf(buff, "%04u", i);
      std::string s(startstring);
      s += buff;
      caridvec.push_back(s);
   }
   //generate some made up callids
   std::vector<callid> tsvec;
   for(int i = 9999; i < 12000; ++i) {
      tsvec.push_back(i);
   }

   //populate map
   for(unsigned i = 0; i < 2000; ++i)
      cmap[tsvec[i]] = std::make_pair(caridvec[i], i+1);

   //expiry handling
   static const int MAXNUMBER = 1000;

   // what I want to do is retain top 1000 with highest timestamps and remove all other entries.  
   // But of course map is ordered by the key
   // what is best approach.  std::transform??
   // just iterate each one.  But then I don't know what my criteria for erasing is until I have
   // found the largest 1000 items
   // std::for_each(cmap.begin(), cmap.end(), cleaner);

   //nth_element seems appropriate.  Do I reverse the map and have key as timestamp, use nth_element 
   //to work out what part to erase, then un-reverse the map as before with 1000 elements
   //std::nth_element(coll.begin(), coll.begin()+MAXNUMBER, coll.end()); 
   //erase from coll.begin()+MAXNUMBER to coll.end()

   return 0;
}

更新:

这是我正在玩的解决方案。

// as map is populated also fill queue with timestamp
std::deque<timestamp> tsq;
for(unsigned i = 0; i < 2000; ++i) {
   cmap[tsvec[i]] = std::make_pair(caridvec[i], i+1);
   tsq.push_back(tsvec[i]);
}
std::cout << "initial cmap size = " << cmap.size() << std::endl;


// expire old entries
static const int MAXNUMBER = 1000;
while(tsq.size() > MAXNUMBER) {
   callid2caridmap::iterator it = cmap.find(tsq.front());
   if(it != cmap.end())
      cmap.erase(it);

   tsq.pop_front();
}

std::cout << "cmap size now = " << cmap.size() << std::endl;

但仍然对任何可能的替代品感兴趣。

1 个答案:

答案 0 :(得分:1)

制作最大堆时间戳 - &gt;迭代器到地图中的对象。 堆将是&lt; = 1000项。 检查当你在堆中插入时,你有&lt; 1000个项目或时间戳是&lt;如果所有这些都有意义的话,堆的最大值并在从堆中弹出项目时执行工作