• 460. LFU缓存


    460. LFU缓存

    有一个疑问,当我的构造函数这个样定义的时候

    Node(int _cnt, int _time, int _key, int _value) {
            cnt = _cnt;
            time = _time;
            key = _key;
            value = _value;
        }

    我这样调用unordered_map是不会通过编译 

    int get(int key) {
            if(capacity == 0) {
                return -1;
            }
    
            auto it = key_value.find(key);
            if(it == key_value.end()) {
                return -1;
            }
    
            Node cache = key_value[key]; // 这一行不能通过编译,cache通过it->second却是能够正常赋值的
    
            s.erase(cache);
            cache.cnt++;
            cache.time = ++time;
            s.insert(cache);
            it->second = cache;
    
            return cache.value;
        }

     

    但是,当我构造函数这个样定义的时候

    
    
      Node(){}
         Node(int _cnt, int _time, int _key, int _value) {
             cnt = _cnt;
             time = _time;
             key = _key;
             value = _value;
         }

     

     Node cache = key_value[key]; 

     

    却能够正确编译,记录一下

     

    代码:

     1 struct Node {
     2     int cnt;
     3     int time;
     4     int key, value;
     5     
     6     Node(){}
     7     Node(int _cnt, int _time, int _key, int _value) {
     8         cnt = _cnt;
     9         time = _time;
    10         key = _key;
    11         value = _value;
    12     }
    13 
    14     bool operator < (const Node& t) const {
    15         return t.cnt == cnt ? time < t.time: cnt < t.cnt; 
    16     }
    17 };
    18 
    19 class LFUCache {
    20     int time;
    21     unordered_map<int, Node> key_value;
    22     set<Node> s;
    23     int capacity;
    24 public:
    25     LFUCache(int _capacity) {
    26         key_value.clear();
    27         time = 0;
    28         s.clear();
    29         capacity = _capacity;
    30     }
    31     
    32     int get(int key) {
    33         if(capacity == 0) {
    34             return -1;
    35         }
    36 
    37         auto it = key_value.find(key);
    38         if(it == key_value.end()) {
    39             return -1;
    40         }
    41         Node cache = key_value[key];
    42         s.erase(cache);
    43         cache.cnt++;
    44         cache.time = ++time;
    45         s.insert(cache);
    46         it->second = cache;
    47 
    48         return cache.value;
    49     }
    50     
    51     void put(int key, int value) {
    52         if(capacity == 0) {
    53             return ;
    54         }
    55 
    56         auto it = key_value.find(key);
    57 
    58         if(it == key_value.end()) {
    59             if(key_value.size() == capacity) {
    60                 key_value.erase(s.begin()->key);
    61                 s.erase(s.begin());
    62             }
    63 
    64                 Node node = Node(1, ++time, key, value);
    65                 key_value.insert(make_pair(key, node));
    66                 s.insert(node);
    67             
    68         }
    69         else {
    70             Node tmp = key_value[key];
    71             s.erase(tmp);
    72             tmp.cnt += 1;
    73             tmp.time = ++time;
    74             tmp.value = value;
    75             it->second = tmp;
    76             s.insert(tmp);
    77         }
    78 
    79     }
    80 };
    81 
    82 /**
    83  * Your LFUCache object will be instantiated and called as such:
    84  * LFUCache* obj = new LFUCache(capacity);
    85  * int param_1 = obj->get(key);
    86  * obj->put(key,value);
    87  */

     方法二:

    每一个频率创建一个链表,然后还有一个unordered_map用作定位

    struct Node {
        int key;
        int val;
        int freq;
        Node(){}
        Node(int _key, int _val, int _freq) {
            key = _key;
            val = _val;
            freq = _freq;
        }
    };
    
    class LFUCache {
        unordered_map<int, list<Node> > key_to_freq;
        unordered_map<int, list<Node>::iterator> key_to_value;
        int capacity;
        int minfreq;
    
    public:
        LFUCache(int _capacity) {
            capacity = _capacity;
            key_to_freq.clear();
            key_to_value.clear();
            minfreq = 0;
        }
        
        int get(int key) {
            if(capacity == 0) {
                return -1;
            }
            auto iter = key_to_value.find(key);
            if(iter == key_to_value.end()) {
                return -1;
            }
            else {
                list<Node>::iterator pos = iter->second;
                int freq = pos->freq, val = pos->val;
                key_to_freq[freq].erase(pos);
    
                if(key_to_freq[freq].size() == 0) {
                    key_to_freq.erase(freq);
                    if(freq == minfreq) {
                        minfreq += 1;
                    }
                }
                
                key_to_freq[freq + 1].push_front(Node(key, val, freq + 1));
                key_to_value[key] = key_to_freq[freq + 1].begin();
                return val;
            }
        }
        
        void put(int key, int value) {
            if(capacity == 0) {
                return ;
            }
            auto iter = key_to_value.find(key);
            if(iter != key_to_value.end()) {
                list<Node>::iterator pos = iter->second;
                int freq = pos->freq, val = pos->val;
                key_to_freq[freq].erase(pos);
                key_to_value.erase(key);
    
                if(key_to_freq[freq].size() == 0) {
                    key_to_freq.erase(freq);
                    if(freq == minfreq) {
                        minfreq += 1;
                    }
                }
    
                key_to_freq[freq + 1].push_front(Node(key, value, freq + 1));
                key_to_value[key] = key_to_freq[freq + 1].begin();
                
    
                return ;
            }
            else {
                if(key_to_value.size() == capacity) {
                    Node pos = key_to_freq[minfreq].back();
                    int  val = pos.val, freq = pos.freq;
                    key_to_value.erase(pos.key);
                    key_to_freq[minfreq].pop_back();
                    if(key_to_freq[minfreq].size() == 0) {
                        key_to_freq.erase(minfreq);
                    }
                }
    
                //Node node = new Node(key, value, 1);
                key_to_freq[1].push_front(Node(key, value, 1));
                key_to_value[key] = key_to_freq[1].begin();
                minfreq = 1;
            } 
            return ;
        }
    };
    
    /**
     * Your LFUCache object will be instantiated and called as such:
     * LFUCache* obj = new LFUCache(capacity);
     * int param_1 = obj->get(key);
     * obj->put(key,value);
     */

     

  • 相关阅读:
    Jenkins 基础篇
    Jenkins 基础篇
    Windows配置Nodejs环境
    Windows配置安装JDK
    Windows安装MySQL
    Ubuntu安装MySQL
    利用中国移动合彩云实现360云盘迁移到百度云
    Linux Shell下的后台运行及其前台的转换
    nova image-list 和 glance image-list 有什么区别
    启动虚拟机时提示我已移动或我已复制选项的详解
  • 原文地址:https://www.cnblogs.com/letlifestop/p/12737631.html
Copyright © 2020-2023  润新知