实现LRU的set与get
分析和代码
/*
实现一个小型的数据存储器
存储器的容量有限
设置某个值获取某个值都会把该值变成最优先的【也就是当存储器满了,会把最不优先的删除】
数据结构:
hash表 + 双端链表
hash表: unordered_map<string, list<_Node*>::iterator> hashtable
双端链表: list<_Node*> doublelist
其中:
class _Node{
public:
string key;
int value;
_Node(string s, int d) :key(s), value(d){}
~_Node(){ cout << " deconstor _node " << endl; }
};
hashtable的string和_Node的string是同一个
hashtable的list<_Node*>::iterator是doublelist的迭代器【这里只把它当做指针,不用于迭代】
注:
C++的list::splice实现list拼接的功能。将源list的内容部分或全部元素删除,拼插入到目的list。
函数有以下三种声明:
void splice ( iterator position, list<T,Allocator>& x );
void splice ( iterator position, list<T,Allocator>& x, iterator i );
void splice ( iterator position, list<T,Allocator>& x, iterator first, iterator last );
函数说明:在list间移动元素:
将x的元素移动到目的list的指定位置,高效的将他们插入到目的list并从x中删除。
目的list的大小会增加,增加的大小为插入元素的大小。x的大小相应的会减少同样的大小。
前两个函数不会涉及到元素的创建或销毁。第三个函数会。
指向被删除元素的迭代器会失效。
*/
class LRU{
public:
LRU(int s) :size(0), capacity(s){
}
~LRU(){
for (auto& node : doublelist){
delete node;
}
}
void set(string s, int d){
if (hashtable.count(s) == 0){
if (count() == capcacity()){
earse(--doublelist.end());
}
_Node* temp = new _Node(s, d);
doublelist.push_front(temp);
hashtable.insert(make_pair(s, doublelist.begin()));
++size;
}
else{
(*hashtable[s])->value = d;
doublelist.splice(doublelist.begin(), doublelist, hashtable[s]);
}
}
int get(string s){
if (hashtable.count(s) != 0){
doublelist.splice(doublelist.begin(), doublelist, hashtable[s]);
return doublelist.front()->value;
}
return INT_MIN;
}
void print(){
for (auto& node : doublelist){
cout << "key " << node->key << " value " << node->value << endl;
}
}
int count(){
return size;
}
int capcacity(){
return capacity;
}
bool isExistence(string key){
return (hashtable.count(key) != 0);
}
private:
class _Node{
public:
string key;
int value;
_Node(string s, int d) :key(s), value(d){
}
~_Node(){
cout << " deconstor _node " << endl; }
};
unordered_map<string, list<_Node*>::iterator> hashtable;
list<_Node*> doublelist;
int size;
int capacity;
void earse(list<_Node*>::iterator iter){
if (iter != doublelist.end()){
string key = (*iter)->key;
_Node* del = (*iter);
doublelist.erase(iter);
hashtable.erase(key);
delete del;
--size;
}
}
};
思考
1、只能存储int