6

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

我在这张地图中只保留了 40 件物品,当我达到 40 件物品时,我想放弃地图中的最后一件物品。我知道我做不到myLocations.erase(myLocations.end()),那我该怎么做呢?

我确实打算让地图中的最后一项是最旧的,因此是 FIFO。数据将很快进入(大约 20Hz),所以我希望地图能跟上它。我确实需要根据时间查找数据,所以我确实需要它作为关键,但我愿意接受其他方法来实现这一点。

字符串的格式是一个非常冗长的“Thursday June 21 18:44:21:281”,但为了简单起见,我可以将其缩减为自纪元以来的秒数。这是我第一次尝试,还没有过多考虑格式。

4

6 回答 6

16

最惯用的方法是:

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

如果您没有 C++11,请使用工具箱中的相应函数。

于 2012-06-21T17:32:30.653 回答
7

试试这个,它有效:

map<string, LocationStruct>::iterator it = myLocations.end();
it--;
myLocations.erase(it);
于 2014-01-25T09:05:01.363 回答
5

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

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

更好的是,使用 a和 use按时间查找元素。这将自动为您删除最旧的,并且在按时间查找元素时具有相同的逻辑复杂度。添加数据时也更快。对于您的情况,这几乎是全赢的。如果您真的想避免,那么 a最适合您的需求,并提供出色的性能,但如果您已经有工作,那么留在 a可能是最好的。boost::circular_buffer<std::pair<timetype, LocationStruct>>std::lower_boundbooststd::dequemapstd::map

以下是如何在 a 中进行查找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;
}
于 2012-06-21T17:14:32.347 回答
2

好吧,对 g++ 4.4 的快速检查表明这很好用:

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

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

于 2012-06-21T17:17:22.173 回答
0

由于您将时间存储为键 String 。最后一个元素(考虑到从 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。即使新数据到达的频率非常慢,这也会引起注意。

于 2012-06-21T17:16:32.823 回答
0

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

myLocations.erase ((--myLocations.end()));
于 2019-05-23T14:24:42.737 回答