私は時間があったので、セットとリストを使ってやりました。リストは、最後に挿入されたn個の要素を追跡します。また、一般的な消去を実装しました。パフォーマンスを向上させるには(setが注文されていることを利用していない場合)、unordered_setの使用を検討することができます。 (include <unordered_set>
ならびにstd::unordered_set
とstd::set
とinclude <set>
を置き換える)
#include <set>
#include <list>
#include <assert.h>
template<typename T>
struct setkeepn {
std::set<T> mSet;
std::list<T> mLast;
void insert(T element) {
if (mSet.find(element) == mSet.end()) {
assert(mSet.size() == mLast.size());
// put your limit of 30 below
if (mSet.size() >= 2) {
T extra = mLast.back();
mSet.erase(extra);
mLast.pop_back();
}
mSet.insert(element);
mLast.push_front(element);
}
}
void erase(T element)
{
typename std::set<T>::iterator lToEraseFromSet = mSet.find(element);
if (lToEraseFromSet != mSet.end()) {
// linear on the number of elements.
typename std::list<T>::iterator lToEraseFromList = std::find(mLast.begin(),mLast.end(), element);
assert(lToEraseFromList != mLast.end());
mSet.erase(lToEraseFromSet);
mLast.erase(lToEraseFromList);
}
}
};
int main(int argc, const char * argv[]) {
setkeepn<int> lTest;
lTest.insert(1);
lTest.insert(2);
lTest.insert(2);
lTest.insert(3);
printf("should see 2 3\n");
for (auto e : lTest.mSet) { // 2,3
printf("elements: %d\n",e);
}
lTest.insert(4);
lTest.erase(3);
printf("should see 4\n");
for (auto e : lTest.mSet) { // 4
printf("elements: %d\n",e);
}
return 0;
}
結果:[製品コードでLRU実装]の
should see 2 3
elements: 2
elements: 3
should see 4
elements: 4
可能重複(http://stackoverflow.com/questions/2057424/プロダクションコードでのlru-implementation) – bdonlan