class LRUCache {
public:
LRUCache(int capacity) : _capacity(capacity) {}
int get(int key) {
if(km_all.count(key) == 0 || !(km_all[key].is_inCache)){
return -1;
// 对于不在Cache中的数字,get没有影响
}
int value = km_all[key].value;
// 对于在Cache中的数,get会更新lru链表。
list<int>::iterator lru_it = km_all[key].page_pointer;//find_if(list_lru.begin(), list_lru.end(), [key](int a){return a == key;});
list_lru.splice(list_lru.begin(), list_lru, lru_it); // 插入到链表头部
return value;
}
void put(int key, int value) {
// 更新key_all表
if(km_all.count(key) == 0){// 如果是一个新加元素
list_lru.insert(list_lru.begin(), key); // 更新lru链表
key_struct new_struct;
new_struct.is_inCache = true;
new_struct.value = value;
new_struct.page_pointer = list_lru.begin();
km_all.insert(make_pair(key, new_struct));
if(list_lru.size() > _capacity){
list<int>::iterator it = list_lru.end();
it--;
km_all[*it].is_inCache = false;
km_all[*it].page_pointer = list_lru.end();
list_lru.erase(it);
}
}
else{
km_all[key].value = value;
if(km_all[key].is_inCache == true){ //如果本来就在Cache中
list<int>::iterator lru_it = km_all[key].page_pointer;//find(list_lru.begin(), list_lru.end(), key);
list_lru.splice(list_lru.begin(), list_lru, lru_it); // 插入到链表头部
//km_all[key].page_pointer = list_lru.begin(); // 其实可以不加这句话
}
else{ // 本来不在链表中
km_all[key].is_inCache = true;
list_lru.insert(list_lru.begin(), key); // 更新lru链表
km_all[key].page_pointer = list_lru.begin();
if(list_lru.size() > _capacity){
list<int>::iterator it = list_lru.end();
it--;
km_all[*it].is_inCache = false;
km_all[*it].page_pointer = list_lru.end();
list_lru.erase(it);
}
}
}
}
private:
struct key_struct{
bool is_inCache;
int value;
list<int>::iterator page_pointer; // 在lru链表中的迭代器不会失效,不在链表中为空
};
unordered_map<int, key_struct> km_all; // 保存所有的key
list<int> list_lru; // lru链表最近使用的放在前面
int _capacity;
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/