快取,就是把資料儲存在本地,簡單實用key-value做乙個對映就好了。但為什麼還要快取策略,因為快取的大小需要限制,否則儲存的東西只增不減,時間一長就有很多記憶體浪費。
因為資源總是有限,所以優化,因為優化所以複雜這個是least recently used的縮寫,即最近最少使用。它的邏輯很簡單:一串資料,a->b->c->d->....->head,新的資料來就壓到頭部,哪個資料用到了也拉到頭部,然後記憶體到了限制額,就丟掉最後的那個。
也就是最近被用到得越多,不管是存還是取,就更能活下來
class lrucache ;
};//頭和尾各設了乙個哨兵指標,方便處理,不用做頭尾的判空
cachenode *head = new cachenode();
cachenode *tail = new cachenode();
int capacity;
int size = 0;
unordered_mapstore;
/** 在頭部插入乙個資料 */
inline void inserthead(cachenode *node)
inline void unbind(cachenode *node)
/** 把節點拉到最前面 */
inline void forword(cachenode *node)
unbind(node);
inserthead(node);
}/** 扔掉最後乙個 */
inline void droptail
()
friend ostream& operator<<(ostream& os, lrucache &cache)
return os;
}public:
lrucache(int capacity)
int get(int key) else
}void set(int key, int value)
auto node = new cachenode(key, value);
store[key] = node;
inserthead(node);
size++;
}else
}};複製**
這是我用雙鏈表實現的乙個lru演算法,快取有兩個關係維護資料:乙個是key-value之間的對映關係,用map字典之類的;另乙個是要維持資料的先後關係,這個先後關係決定了哪些資料會被丟棄,就要類似陣列子類的結構,可以直接使用系統庫提供的陣列,也可以自己用雙鏈表來做。
如果要讓這個演算法更使用,還需要:
這個是least frequently used的縮寫,表示最近最不常用。意思上跟lru好像是一樣的,最大的區別是:lru是使用一次就被提到最前面,而lfu是用一次標記一下,然後按照這個使用次數來排序。換言之,lfu有更精確的統計。
同樣是乙個資料佇列,模擬一下操作過程:
下面是乙個演算法實現,為了提高效率,使用分層結構:把time相同的節點放在乙個佇列裡,然後用乙個大佇列把這些佇列串起來。因為在資料往前提都是直接越過了time相同的那一層,去到上一層的第乙個。如果time相同的資料過多,時間消耗倍增。
class lfucache ;
bool operator==(const keynode &other) const
};struct rownode;
rownode *next = nullptr;
rownode *pre = nullptr;
keynode *keyhead = nullptr;
keynode *keytail = nullptr;
};rownode *lastrow = nullptr;
int capacity = 0;
int storedsize = 0;
unordered_mapstore;
void bringforward(keynode *node)
removekeynode(node);
if (node->row->keyhead == nullptr && node->row == lastrow)
insertnodetofront(node, prerow);
}inline void insertnodetofront(keynode *node, rownode *row)
node->next = row->keyhead;
node->pre = nullptr;
if (row->keyhead) else
row->keyhead = node;
node->row = row;
}inline void removekeynode(keynode *node)else
}else
if (node->row->keytail == node)
}public:
lfucache(int capacity)
void set(int key, int value)
keynode *newnode = nullptr;
if (storedsize == capacity)
}else
if (lastrow->time != 1)
store[key] = newnode;
insertnodetofront(newnode, lastrow);
}int get(int key)
keynode *find = store[key];
bringforward(find);
return find->value;
}};複製**
最後這裡是我的演算法練習庫 快取淘汰演算法 LRU 和 LFU
lru least recently used 即最近最少使用演算法,是一種常見的 cache 頁面置換演算法,有利於提高 cache 命中率。lru 的演算法思想 對於每個頁面,記錄該頁面自上一次被訪問以來所經歷的時間 t 當淘汰乙個頁面時,應選擇所有頁面中其 t 值最大的頁面,即記憶體中最近一段...
LFU快取策略
example lfucache cache new lfucache 2 capacity cache.put 1,1 cache.put 2,2 cache.get 1 returns 1 cache.put 3,3 evicts key 2 cache.get 2 returns 1 not ...
C 實現快取演算法LRU和LFU
運用你所掌握的資料結構,設計和實現乙個lru 最近最少使用 快取機制 它應該支援以下操作 獲取資料get和 寫入資料put。獲取資料get key 如果金鑰 key 存在於快取中,則獲取金鑰的值 總是正數 否則返回 1。寫入資料put key,value 如果金鑰不存在,則寫入其資料值。當快取容量達...