6

私のマップは次のように定義されて map<string, LocationStruct> myLocations;います。キーは時間文字列です

このマップには 40 個のアイテムしか保持していません。40 個のアイテムに達したら、マップの最後のアイテムを削除したいと考えています。できないことはわかっているmyLocations.erase(myLocations.end())ので、どうすればいいですか?

マップの最後のアイテムが最も古いものになるように意図しているため、FIFO になります。データはかなり速く (約 20Hz) 入ってくるので、マップがそれに追いつくことができることを願っています。時間に基づいてデータを検索する必要があるため、それが鍵になる必要がありますが、これを達成するための別の方法を受け入れています。

文字列の形式は非常に冗長な「6 月 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を使用するのがおそらく最善です。boost::circular_buffer<std::pair<timetype, LocationStruct>>std::lower_boundbooststd::dequemapstd::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;
}
于 2012-06-21T17:14:32.347 に答える
2

さて、g++ 4.4 を簡単にチェックすると、これは問題なく動作することがわかります。

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

告白しなければなりませんが、イテレータ自体だけを受け入れるのが好きではない理由がわかりません。

于 2012-06-21T17:17:22.173 に答える
0

キー文字列として時間を保存しているので。最後の要素(00:00から24:00までの時間を考慮して1日の時間で最も早い)は下限要素になるため、次のようにイテレータをフェッチできます。

     `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 に答える