LRU快取機制(Python and C 解法)

2022-08-24 19:15:13 字數 3444 閱讀 6712

運用你所掌握的資料結構,設計和實現乙個  lru (最近最少使用) 快取機制。它應該支援以下操作: 獲取資料 get 和 寫入資料 put 。

獲取資料 get(key) - 如果關鍵字 (key) 存在於快取中,則獲取關鍵字的值(總是正數),否則返回 -1。

寫入資料 put(key, value) - 如果關鍵字已經存在,則變更其資料值;如果關鍵字不存在,則插入該組「關鍵字/值」。當快取容量達到上限時,它應該在寫入新資料之前刪除最久未使用的資料值,從而為新的資料值留出空間。

示例:lrucache cache = new lrucache( 2 /* 快取容量 */ );

cache.put(1, 1);

cache.put(2, 2);

cache.get(1); // 返回 1

cache.put(3, 3); // 該操作會使得關鍵字 2 作廢

cache.get(2); // 返回 -1 (未找到)

cache.put(4, 4); // 該操作會使得關鍵字 1 作廢

cache.get(1); // 返回 -1 (未找到)

cache.get(3); // 返回 3

cache.get(4); // 返回 4

設計的必要條件:

1.快取中的元素必須有時序,以區分最近使用的和久未使用的資料,當容量滿了之後要刪除最久未使用的那個元素,騰出位置。

2.要在快取中快速找某個key是否已存在並得到對應的value;

3.每次訪問快取中的某個key,需要將這個元素變為最近使用的,也就是說快取要支援在任意位置快速插入和刪除元素。

設計:

雜湊表查詢快,但是資料無固定順序;雙向鍊錶有順序之分,插入刪除快,但是查詢慢。所以結合形成一種新的資料結構:雜湊鍊錶。lru快取演算法的核心資料結構就是雜湊鍊錶,雙向鍊錶和雜湊表的結合體。

每次預設從鍊錶頭部新增元素,那麼越靠頭部的元素就是最近使用的,越靠尾部的元素就是最久未使用的。

對於某乙個key,可以通過雜湊表快速定位到鍊錶中的節點,從而取得對應value。

雙向鍊錶可以獲得前驅指標,支援在任意位置快速插入和刪除,但是鍊錶無法按照索引快速訪問某乙個位置的元素,而借助雜湊表,可以通過key快速對映到任意乙個鍊錶節點,然後進行插入和刪除。

雜湊表中已經儲存key,鍊錶中還要儲存key的原因:當快取已滿,不僅要刪除鍊錶節點,還要把雜湊表中對映到該節點的key同時刪除,而這個key只能由鍊錶節點得到,如果鍊錶節點中只儲存value,那麼就無法得知key,就無法刪除雜湊表中的key。

1

class

lrucache:23

def__init__

(self, capacity: int):

4 self.dict = collections.ordereddict() #

有序字典

5 self.remain =capacity67

def get(self, key: int) ->int:

8if key not

in self.dict: return -1

9 v = self.dict.pop(key) #

取出該值並刪除它

10 self.dict[key] = v #

將其重新放回快取,且處於頂部(由於是有序字典)

11returnv12

13def put(self, key: int, value: int) ->none:

14if key in self.dict: #

如果key存在,則應先將其value刪除再更新為新值

15self.dict.pop(key)

16else: #

如果key不存在17#

快取未滿,放入新數值,容量減一

18if self.remain > 0: self.remain -= 1 19#

快取已滿,放入新數值,popitem返回並刪除字典中的最後一對鍵和值20#

last=false,以佇列方式彈出鍵值對,last=true,以堆疊方式彈出鍵值對

21else: self.dict.popitem(last =false)

22 self.dict[key] = value #

寫入新資料

2324

#your lrucache object will be instantiated and called as such:25#

obj = lrucache(capacity)26#

param_1 = obj.get(key)27#

obj.put(key,value)

1

struct

dlinkednode //

預設初始化

10 dlinkednode(int _key, int

_value): key(_key),value(_value),prev(null),next(null) {}

11};

1213

class

lrucache

28void addtohead(dlinkednode *node)

34void removenode(dlinkednode *node)

38void movetohead(dlinkednode *node)

42 dlinkednode *removetail()

4748

49int

get(int

key) 57}

5859

void put(int key, int

value)

69 cache[key] = newnode; //

新節點新增進雜湊表中

70 addtohead(newnode); //

新增至鍊錶頭部,由於同一key,故可通過雜湊表定位該節點 71}

72else77}

78};

7980/**

81* your lrucache object will be instantiated and called as such:

82* lrucache* obj = new lrucache(capacity);

83* int param_1 = obj->get(key);

84* obj->put(key,value);

85*/

LRU快取機制

運用你所掌握的資料結構,設計和實現乙個 lru 最近最少使用 快取機制。它應該支援以下操作 獲取資料 get 和 寫入資料 put 獲取資料 get key 如果金鑰 key 存在於快取中,則獲取金鑰的值 總是正數 否則返回 1。寫入資料 put key,value 如果金鑰不存在,則寫入其資料值。...

LRU快取機制

運用你所掌握的資料結構,設計和實現乙個 lru 最近最少使用 快取機制。它應該支援以下操作 獲取資料 get 和 寫入資料 put 獲取資料 get key 如果金鑰 key 存在於快取中,則獲取金鑰的值 總是正數 否則返回 1。寫入資料 put key,value 如果金鑰不存在,則寫入其資料值。...

LRU快取機制

lru快取機制 最近最少使用 雙向鍊錶 雜湊表 不使用自帶 linkedhashmap 雙向鍊錶按照被使用的順序儲存了這些鍵值對,靠近頭部的鍵值對是最近使用的,而靠近尾部的鍵值對是最久未使用的。雜湊錶即為普通的雜湊對映 hashmap 通過快取資料的鍵對映到其在雙向鍊錶中的位置。首先使用雜湊表進行定...