Advertisement
yarin0600

Untitled

Nov 16th, 2023
891
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.45 KB | None | 0 0
  1. #include <iostream>
  2. #include <list>
  3. #include <unordered_map>
  4.  
  5. class LFUCache
  6. {
  7. public:
  8.     LFUCache(int capacity)
  9.     {
  10.         _capacity = capacity;
  11.     }
  12.  
  13.     int get(int key)
  14.     {
  15.         if (!_keyToIterators.count(key))
  16.             return -1;
  17.  
  18.         updateUsage(key);
  19.  
  20.         return *_keyToIterators[key].second;
  21.     }
  22.  
  23.     void put(int key, int value)
  24.     {
  25.         if (_keyToIterators.count(key))
  26.         {
  27.             updateUsage(key);
  28.             *_keyToIterators[key].second = value;
  29.         }
  30.         else
  31.         {
  32.             if (_frequencies.size() == _capacity)
  33.             {
  34.                 _keyToIterators.erase(); // TODO: remove the key of LFU & LRU key,val.
  35.                 _frequencies.front().values.pop_back();
  36.             }
  37.             if (!_frequencies.empty() && _frequencies.front().values.empty())
  38.                 _frequencies.pop_front();
  39.             if (!_frequencies.empty() && 1 == _frequencies.front().frequency)
  40.                 _frequencies.front().values.push_front(value);
  41.             else
  42.                 _frequencies.push_front({ .frequency = 1, .values = {value} });
  43.             _keyToIterators[key] = { _frequencies.begin(),
  44.                                     _frequencies.begin()->values.begin() };
  45.             // std::cout << "_frequencies.begin()->frequency = " <<  _frequencies.begin()->frequency << std::endl;
  46.             // std::cout << "_frequencies.begin().front().values.begin() = " <<  *(_frequencies.begin() << std::endl;
  47.         }
  48.     }
  49.  
  50. private:
  51.     void updateUsage(int key)
  52.     {
  53.         auto [elementFreqIt, elementIt] = _keyToIterators[key];
  54.         // std::pair<std::list<Item>::iterator, std::list<int>::iterator> p = ;
  55.  
  56.         // std::list<Item>::iterator elementFreqIt = _keyToIterators[key].first;
  57.         // std::list<int>::iterator elementIt = _keyToIterators[key].second;
  58.  
  59.         auto nextFreqIt = std::next(elementFreqIt);
  60.         int value = *elementIt;
  61.         int currentFreq = elementFreqIt->frequency;
  62.  
  63.         elementFreqIt->values.erase(elementIt);
  64.  
  65.         if (_frequencies.end() == nextFreqIt ||
  66.             nextFreqIt->frequency - 1 != currentFreq)
  67.         {
  68.             auto insertIt = _frequencies.insert(
  69.                 nextFreqIt, { .frequency = currentFreq + 1, .values = {value} });
  70.             _keyToIterators[key] = { insertIt, insertIt->values.begin() };
  71.         }
  72.         else
  73.         {
  74.             nextFreqIt->values.push_front(value);
  75.             _keyToIterators[key] = { nextFreqIt, nextFreqIt->values.begin() };
  76.         }
  77.  
  78.         if (elementFreqIt->values.empty())
  79.             _frequencies.erase(elementFreqIt);
  80.     }
  81.  
  82. public:
  83.     struct Item
  84.     {
  85.         int frequency;
  86.         std::list<int> values;
  87.     };
  88.  
  89.     int _capacity;
  90.     std::list<Item> _frequencies;
  91.     std::unordered_map<
  92.         int, std::pair<std::list<Item>::iterator, std::list<int>::iterator>>
  93.         _keyToIterators;
  94. };
  95.  
  96. int main(int argc, char** argv)
  97. {
  98.     LFUCache lfu(2);
  99.     lfu.put(1, 1);                                           // cache=[1,_], cnt(1)=1
  100.     lfu.put(2, 2);                                           // cache=[2,1], cnt(2)=1, cnt(1)=1
  101.     std::cout << "lfu.get(1) = " << lfu.get(1) << std::endl; // return 1
  102.                                                              // cache=[1,2], cnt(2)=1, cnt(1)=2
  103.     lfu.put(3, 3);                                           // 2 is the LFU key because cnt(2)=1 is the smallest,
  104.                                                              // invalidate 2. cache=[3,1], cnt(3)=1, cnt(1)=2
  105.     std::cout << "lfu.get(2) = " << lfu.get(2) << std::endl; // return -1 (not found)
  106.     std::cout << "lfu.get(3) = " << lfu.get(3) << std::endl; // return 3
  107.                                                              // cache=[3,1], cnt(3)=2, cnt(1)=2
  108.     lfu.put(4, 4);                                           // Both 1 and 3 have the same cnt, but 1 is LRU, invalidate 1.
  109.                                                              // cache=[4,3], cnt(4)=1, cnt(3)=2
  110.     std::cout << "lfu.get(1) = " << lfu.get(1) << std::endl; // return -1 (not found)
  111.     std::cout << "lfu.get(3) = " << lfu.get(3) << std::endl; // return 3
  112.                                                              // cache=[3,4], cnt(4)=1, cnt(3)=3
  113.     std::cout << "lfu.get(4) = " << lfu.get(4) << std::endl; // return 4
  114.                                                              // cache=[4,3], cnt(4)=2, cnt(3)=3
  115.     return 0;
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement