boollookup(stringk,int&val){/* find a matching item */autoit=CacheEntries.find(k);if(it==CacheEntries.end()){//not foundreturnfalse;}val=(*it).second->value;//found/* update linked list */detach((*it).second);//detachpush_front((*it).second);//add to the head because this is the latestreturntrue;}

voidput(stringk,intval){/* find a matching item: O(1) operation */autoit=CacheEntries.find(k);if(it!=CacheEntries.end()){//found/* update data */(*it).second->value=val;/* update linked list */detach((*it).second);//detachpush_front((*it).second);//add to the head because this is the latestreturn;}/* Add new one: O(1) operation */if(CacheEntries.size()!=MaxNumEntries){//Cache is NOT fullItem*t=newItem(k,val);pair<string,Item*>entry(k,t);CacheEntries.insert(entry);push_front(t);//Latest one}else{//Cache is full/* Select Victim & delete */stringkey;back(key);//get the key of the oldest onepop_back();//remove the oldest oneautort=CacheEntries.find(key);if(rt!=CacheEntries.end()){//foundCacheEntries.erase(rt);//delete}Item*t=newItem(k,val);pair<string,Item*>entry(k,t);CacheEntries.insert(entry);push_front(t);//Latest one}}

code

#include<iostream>#include<unordered_map>#include<string>usingnamespacestd;structItem{stringkey;intvalue;Item*prev;Item*next;Item(stringk,intv):key(k),value(v){prev=NULL;next=NULL;}};classCache{public:virtualboollookup(stringkey,int&val)=0;virtualvoidput(stringkey,intval)=0;};classLRUCache:publicCache{private:/* Doubly Linked List: Head - The most recent, Tail - The least recent */Item*head;Item*tail;voiddetach(Item*item){//Detach item from linked list : O(1)item->next->prev=item->prev;item->prev->next=item->next;};voidpush_front(Item*item){//Add the new item at the front : O(1)item->next=head->next;head->next->prev=item;head->next=item;item->prev=head;};voidpop_back(){//delete item from the tail : O(1)Item*item=tail->prev;if(item!=head){tail->prev=item->prev;deleteitem;}else{tail->prev=head;}tail->prev->next=tail;};boolback(string&key){//Get the item from the tail: O(1)if(tail->prev==head){returnfalse;}key=tail->prev->key;returntrue;};/* Hash Table */intMaxNumEntries;unordered_map<string,Item*>CacheEntries;public:LRUCache(intnum):MaxNumEntries(num){//head <-> tailhead=newItem("0",0);tail=newItem("0",0);head->next=tail;tail->prev=head;};~LRUCache(){while(head->next!=tail){pop_back();}deletehead;deletetail;}boollookup(stringk,int&val){/* find a matching item */autoit=CacheEntries.find(k);if(it==CacheEntries.end()){//not foundreturnfalse;}val=(*it).second->value;//found/* update linked list */detach((*it).second);//detachpush_front((*it).second);//add to the head because this is the latestreturntrue;}voidput(stringk,intval){/* find a matching item: O(1) operation */autoit=CacheEntries.find(k);if(it!=CacheEntries.end()){//found/* update data */(*it).second->value=val;/* update linked list */detach((*it).second);//detachpush_front((*it).second);//add to the head because this is the latestreturn;}/* Add new one: O(1) operation */if(CacheEntries.size()!=MaxNumEntries){//Cache is NOT fullItem*t=newItem(k,val);pair<string,Item*>entry(k,t);CacheEntries.insert(entry);push_front(t);//Latest one}else{//Cache is full/* Select Victim & delete */stringkey;back(key);//get the key of the oldest onepop_back();//remove the oldest oneautort=CacheEntries.find(key);if(rt!=CacheEntries.end()){//foundCacheEntries.erase(rt);//delete}Item*t=newItem(k,val);pair<string,Item*>entry(k,t);CacheEntries.insert(entry);push_front(t);//Latest one}}};intmain(){LRUCachecache(5);cache.put("A",1);cache.put("B",2);cache.put("C",3);cache.put("D",4);cache.put("E",5);intval;if(cache.lookup("A",val)){//'A' is updated. So 'B' becomes the oldest.cout<<"A's value is "<<val<<endl;//expected result}else{cout<<"A: Not found"<<endl;}cache.put("F",6);//Cache replacement. 'B' is removed and 'C' becomes the oldestif(cache.lookup("B",val)){cout<<"B's value is "<<val<<endl;}else{cout<<"B: Not found"<<endl;//expected}cache.put("C",7);//'C' is updated. Now 'D' becomes the oldestif(cache.lookup("C",val)){cout<<"C's value is "<<val<<endl;//expected}else{cout<<"C: Not found"<<endl;}cache.put("G",8);//Cache replacement. 'D' is removed and 'E' becomes the oldestif(cache.lookup("D",val)){cout<<"D's value is "<<val<<endl;}else{cout<<"D: Not found"<<endl;//expected result}return0;}

template

template을 이용해 입력 type을 컴파일 타임에 결정하게 한 코드는 다음과 같다.

#include<iostream>#include<unordered_map>#include<string>usingnamespacestd;template<classK,classV>structItem{Kkey;Vvalue;Item*prev;Item*next;Item(stringk,intv):key(k),value(v){prev=NULL;next=NULL;}};template<classK,classV>classCache{public:virtualboollookup(Kkey,V&val)=0;virtualvoidput(Kkey,Vval)=0;};template<classK,classV>classLRUCache:publicCache<K,V>{private:/* Doubly Linked List: Head - The most recent, Tail - The least recent */Item<K,V>*head;Item<K,V>*tail;voiddetach(Item<K,V>*item){//Detach item from linked list : O(1)item->next->prev=item->prev;item->prev->next=item->next;};voidpush_front(Item<K,V>*item){//Add the new item at the front : O(1)item->next=head->next;head->next->prev=item;head->next=item;item->prev=head;};voidpop_back(){//delete item from the tail : O(1)Item<K,V>*item=tail->prev;if(item!=head){tail->prev=item->prev;deleteitem;}else{tail->prev=head;}tail->prev->next=tail;};boolback(K&key){//Get the item from the tail: O(1)if(tail->prev==head){returnfalse;}key=tail->prev->key;returntrue;};/* Hash Table */intMaxNumEntries;unordered_map<K,Item<K,V>*>CacheEntries;public:LRUCache(intnum):MaxNumEntries(num){//head <-> tailhead=newItem<K,V>("0",0);tail=newItem<K,V>("0",0);head->next=tail;tail->prev=head;};~LRUCache(){while(head->next!=tail){pop_back();}deletehead;deletetail;}boollookup(Kk,V&val){/* find a matching item */autoit=CacheEntries.find(k);if(it==CacheEntries.end()){//not foundreturnfalse;}val=(*it).second->value;//found/* update linked list */detach((*it).second);//detachpush_front((*it).second);//add to the head because this is the latestreturntrue;}voidput(Kk,Vval){/* find a matching item: O(1) operation */autoit=CacheEntries.find(k);if(it!=CacheEntries.end()){//found/* update data */(*it).second->value=val;/* update linked list */detach((*it).second);//detachpush_front((*it).second);//add to the head because this is the latestreturn;}/* Add new one: O(1) operation */if(CacheEntries.size()!=MaxNumEntries){//Cache is NOT fullItem<K,V>*t=newItem<K,V>(k,val);pair<K,Item<K,V>*>entry(k,t);CacheEntries.insert(entry);push_front(t);//Latest one}else{//Cache is full/* Select Victim & delete */Kkey;back(key);//get the key of the oldest onepop_back();//remove the oldest oneautort=CacheEntries.find(key);if(rt!=CacheEntries.end()){//foundCacheEntries.erase(rt);//delete}Item<K,V>*t=newItem<K,V>(k,val);pair<K,Item<K,V>*>entry(k,t);CacheEntries.insert(entry);push_front(t);//Latest one}}};intmain(){LRUCache<string,int>cache(5);cache.put("A",1);cache.put("B",2);cache.put("C",3);cache.put("D",4);cache.put("E",5);intval;if(cache.lookup("A",val)){//'A' is updated. So 'B' becomes the oldest.cout<<"A's value is "<<val<<endl;//expected result}else{cout<<"A: Not found"<<endl;}cache.put("F",6);//Cache replacement. 'B' is removed and 'C' becomes the oldestif(cache.lookup("B",val)){cout<<"B's value is "<<val<<endl;}else{cout<<"B: Not found"<<endl;//expected}cache.put("C",7);//'C' is updated. Now 'D' becomes the oldestif(cache.lookup("C",val)){cout<<"C's value is "<<val<<endl;//expected}else{cout<<"C: Not found"<<endl;}cache.put("G",8);//Cache replacement. 'D' is removed and 'E' becomes the oldestif(cache.lookup("D",val)){cout<<"D's value is "<<val<<endl;}else{cout<<"D: Not found"<<endl;//expected result}return0;}