1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| #include <iostream> #include <unordered_map> #include <list> #include <vector> #include <algorithm>
class LFUCache { private: struct Node { int key; int value; int freq; Node(int k, int v, int f) : key(k), value(v), freq(f) {} }; int capacity; int minFreq; std::unordered_map<int, std::list<Node>::iterator> keyNodeMap; std::unordered_map<int, std::list<Node>> freqListMap;
public: LFUCache(int cap) : capacity(cap), minFreq(0) {}
int get(int key) { if (keyNodeMap.find(key) == keyNodeMap.end()) { return -1; } auto nodeIt = keyNodeMap[key]; int value = nodeIt->value; int freq = nodeIt->freq; freqListMap[freq].erase(nodeIt); if (freqListMap[freq].empty()) { freqListMap.erase(freq); if (minFreq == freq) { minFreq++; } }
freq++; freqListMap[freq].emplace_front(key, value, freq); keyNodeMap[key] = freqListMap[freq].begin(); return value; }
void put(int key, int value) { if (capacity == 0) return; if (keyNodeMap.find(key) != keyNodeMap.end()) { auto nodeIt = keyNodeMap[key]; nodeIt->value = value; get(key); return; } if (keyNodeMap.size() >= capacity) { auto nodeToEvict = freqListMap[minFreq].back(); keyNodeMap.erase(nodeToEvict.key); freqListMap[minFreq].pop_back(); if (freqListMap[minFreq].empty()) { freqListMap.erase(minFreq); } }
minFreq = 1; freqListMap[minFreq].emplace_front(key, value, minFreq); keyNodeMap[key] = freqListMap[minFreq].begin(); } };
int main() { LFUCache cache(2);
cache.put(1, 1); cache.put(2, 2); std::cout << "Get 1: " << cache.get(1) << std::endl; cache.put(3, 3); std::cout << "Get 2: " << cache.get(2) << std::endl; std::cout << "Get 3: " << cache.get(3) << std::endl; cache.put(4, 4); std::cout << "Get 1: " << cache.get(1) << std::endl; std::cout << "Get 3: " << cache.get(3) << std::endl; std::cout << "Get 4: " << cache.get(4) << std::endl;
return 0; }
|