LRU

ponder776發表於2024-07-02
#include <iostream>
#include <unordered_map>
#include <list>

using namespace std;

class LRUCache {
private:
    int capacity;
    unordered_map<int, pair<int, list<int>::iterator>> cache;
    list<int> lruList;

public:
    LRUCache(int capacity) {
        this->capacity = capacity;
    }
    
    int get(int key) {
        if (cache.find(key) != cache.end()) {
            // 更新訪問順序
            lruList.splice(lruList.begin(), lruList, cache[key].second);
            return cache[key].first;
        } else {
            return -1;
        }
    }
    
    void put(int key, int value) {
        if (cache.find(key) != cache.end()) {
            // 如果已經存在,更新值並更新訪問順序
            cache[key].first = value;
            lruList.splice(lruList.begin(), lruList, cache[key].second);
        } else {
            // 如果不存在,插入新值
            if (cache.size() >= capacity) {
                // 移除最久未使用的元素
                int lruKey = lruList.back();
                cache.erase(lruKey);
                lruList.pop_back();
            }
            // 插入新元素
            lruList.push_front(key);
            cache[key] = {value, lruList.begin()};
        }
    }
};

int main() {
    LRUCache lruCache(2);

    lruCache.put(1, 1);
    lruCache.put(2, 2);
    cout << lruCache.get(1) << endl; // 輸出 1
    lruCache.put(3, 3);
    cout << lruCache.get(2) << endl; // 輸出 -1,因為鍵 2 不再快取中
    lruCache.put(4, 4);
    cout << lruCache.get(1) << endl; // 輸出 -1,因為鍵 1 不再快取中
    cout << lruCache.get(3) << endl; // 輸出 3
    cout << lruCache.get(4) << endl; // 輸出 4

    return 0;
}

實現說明:

  • LRUCache 類:透過雙向連結串列 lruList 記錄訪問順序,雜湊表 cache 用於快速查詢鍵值對。

  • 建構函式:初始化快取容量 capacity

  • get 方法:根據給定的鍵 key 返回對應的值。如果存在於快取中,則將其移到連結串列頭部表示最近使用;否則返回 -1

  • put 方法:插入或更新快取。如果鍵已存在,則更新其值,並將其移到連結串列頭部。如果快取達到容量上限,則淘汰最近最少使用的元素,並在連結串列頭部插入新元素。

  • main 函式:示例展示瞭如何使用 LRUCache 類,進行插入、獲取操作,並驗證LRU演算法的正確性。

這個實現基於雜湊表和雙向連結串列實現了高效的LRU快取,保證了O(1)時間複雜度的get和put操作。

相關文章