std :: map - 擦除最后一个元素

时间:2012-06-21 17:07:44

标签: c++ stl map erase

我的地图定义如下: map<string, LocationStruct> myLocations;其中键是时间字符串

我只保留此地图中的40个项目,并且当我达到40个项目时,我想放弃地图中的最后一个项目。我知道我不能做myLocations.erase(myLocations.end()),所以我该怎么做呢?

我打算让地图中的最后一项成为最早的项目,因此也是FIFO。数据会很快(大约20Hz)进来,所以我希望地图可以跟上它。我确实需要根据时间查找数据,所以我确实需要它作为关键,但我愿意采用其他方法来实现这一目标。

字符串的格式是一个非常详细的“星期六6月21日18:44:21:281”,尽管我可以把它简化为简单时代以来的秒数。这是我的第一次尝试,并没有过多考虑这种格式。

6 个答案:

答案 0 :(得分:11)

最惯用的方式是:

myLocations.erase( std::prev( myLocations.end() ) );

如果您没有C ++ 11,请使用您的相应功能 工具箱。

答案 1 :(得分:6)

我假设当你说“擦除最后一个元素”时,你的意思是“擦除最旧的元素”。

我不会多次使用字符串,而是使用日期/时间类型(如unix时间戳)。然后他们将按时间排序,而不是按字典顺序排序,你可以myLocations.erase(myLocations.begin()),因为最老的人总是在开头。

更好的是,使用boost::circular_buffer <std::pair<timetype, LocationStruct>>,并使用std::lower_bound按时间查找元素。这将自动删除最旧的,并且在按时间查找元素时具有相同的对数复杂度。添加数据时速度也更快。对于你的情况来说,它几乎全赢。如果你真的想避免boost,那么std::deque最能满足你的需求,并提供出色的表现,但是如果你已经有了map,那么保持std::map可能是最好的。

以下是deque

中的查找方法
typedef ???? timetype;
typedef std::pair<Timetype, LocationStruct> TimeLocPair
typedef std::deque<TimeLocPair> LocationContainer;
typedef LocationContainer::const_iterator LocationIterator;

bool compareTimeLocPair(const TimeLocPair& lhs, const TimeLocPair& rhs)
{return lhs.first < rhs.first;}

LocationIterator find(const LocationContainer& cont, timetype time) {
    TimeLocPair finder(time, LocationStruct());
    LocationIterator it = std::lower_bound(cont.begin(), cont.end(), finder, compareTimeLocPair);
    if (it == cont.end() || it->first != time)
        return cont.end();
    return it;
}

答案 2 :(得分:6)

试试这个,它有效:

map<string, LocationStruct>::iterator it = myLocations.end();
it--;
myLocations.erase(it);

答案 3 :(得分:1)

嗯,快速检查g ++ 4.4表明这很好用:

myLocations.erase(myLocations.rbegin()->first);

虽然我必须承认我不知道为什么它不喜欢只接受迭代器本身。

答案 4 :(得分:0)

因为您将时间存储为键字符串。最后一个元素(考虑从00:00到24:00的时间在一天中最早的时间)将是一个下限元素,因此你可以像这样获取迭代器

     `map<string, LocationStruct>::iterator it;`
      it=myLocations.lower_bound ('00:00');
      myLocations.erase ( it, it+1);

if it belongs to different dates那么您甚至需要考虑当天并相应地对您的代码进行操作。正如您所提到的data is coming quick enough,您不需要考虑日期。但是The safe way here would be take the entire date in terms of second and remove the lowest one as mentioned above。即使新数据到达的频率非常慢,这也会很谨慎。

答案 5 :(得分:0)

map::erase对于没有TS绑定的最后一个元素,只需使用以下内容:

myLocations.erase ((--myLocations.end()));