首先是LRU的定義,LRU表示最近最少使用,如果數據最近被訪問過,那麼將來被訪問的幾率也更高。 所以邏輯應該是每次都要將新被訪問的頁放到列表頭部,如果超過了list長度限制,就將列表尾部的元素踢出去。 主要結構,STL中的雙向鏈表結構list。 主要操作有get,表示訪問key對應的value,此時 ...
首先是LRU的定義,LRU表示最近最少使用,如果數據最近被訪問過,那麼將來被訪問的幾率也更高。
所以邏輯應該是每次都要將新被訪問的頁放到列表頭部,如果超過了list長度限制,就將列表尾部的元素踢出去。
主要結構,STL中的雙向鏈表結構list。
主要操作有get,表示訪問key對應的value,此時要查詢雙鏈表,找到key對應value,再將其從list中刪除,插入到list的頭部。
set, 表示設置對應的key值為value,此時先找到key對應的元素,將其從list中刪除,再插入到list的頭部。
這裡設置了兩個輔助函數remove和setHead,分別負責刪除元素和將元素加入到list頭部。
代碼實現如下:
#include <iostream> #include <list> #include <iterator> #include <algorithm> using namespace std; class LRUNode { public: int key,value; LRUNode(int _key,int _value):key(_key),value(_value) { } bool operator==(LRUNode * p) { return key==p->key; } }; class LRU { public: int get(int key); void set(int key,int val); LRU(int _cap):cap(_cap) { } int cap;//代表存放的最大頁數 void remove(int key); void setHead(int key,int val); void printLis(); list<LRUNode *> lis; }; void LRU::printLis() { list<LRUNode *>::iterator it; for(it=lis.begin();it!=lis.end();it++) { cout<<(*it)->key<<" "<<(*it)->value<<endl; } cout<<endl; } void LRU::remove(int key) { LRUNode * searchNode=new LRUNode(key,0); list<LRUNode *>::iterator it=find(lis.begin(),lis.end(),searchNode); if(it!=lis.end()) { lis.remove(*it); } } void LRU::setHead(int key,int val) { lis.push_front(new LRUNode(key,val)); } int LRU::get(int key) { LRUNode * searchNode=new LRUNode(key,0); list<LRUNode *>::iterator it=find(lis.begin(),lis.end(),searchNode); if(it!=lis.end()) { remove((*it)->key); setHead((*it)->key,(*it)->value); return (*it)->value; } return -1;//表示沒有找到 } void LRU::set(int key,int value) { if(lis.size()>=cap) { lis.pop_back(); } LRUNode * searchNode=new LRUNode(key,0); list<LRUNode *>::iterator it=find(lis.begin(),lis.end(),searchNode); if(it!=lis.end()) { remove(key); setHead(key,value); } else { setHead(key,value); } } int main() { LRU * lru=new LRU(5); lru->set(1,1); lru->printLis(); lru->set(2,2); lru->printLis(); lru->set(3,3); lru->printLis(); lru->set(4,4); lru->printLis(); lru->set(5,5); lru->printLis(); lru->set(6,6); lru->printLis(); lru->set(7,7); lru->printLis(); return 0; }
運行結果:
1 1 2 2 1 1 3 3 2 2 1 1 4 4 3 3 2 2 1 1 5 5 4 4 3 3 2 2 1 1 6 6 5 5 4 4 3 3 2 2 7 7 6 6 5 5 4 4 3 3