I am trying to write C++ code to implement a cache. The cache uses Least Recently Used policy explained by the behaviour:
- If the cache has a capacity to store 5 keys like
5 3 2 1 4then if nextkey=1comes as a hit, the cache order becomes1 5 3 2 4. - If next
key=6comes as a miss, the cache order becomes6 1 5 3 2.
Code I have written below works for Test case 1 and its Output, but not for Test case 2 and its Output. I have shown my code, inputs, and expected outputs below.
Code:
#include <iostream>
#include <map>
#include <list>
#include <algorithm>
using namespace std;
struct Node {
int value, key;
Node (int k,int v):value(v),key(k){};
}typedef Node;
class Cache{
protected :
list <Node> l;
map<int, list<Node>::iterator> mp;
int cp;
virtual void set(int,int) =0;
virtual int get(int)=0;
}typedef Cache;
class LRUCache:public Cache{
void removeback(){
mp.erase(--l.end()->key);
l.pop_back();
}
void addatfront(int k, int v) {
Node *node = new Node(k,v);
if (mp.size() == cp)
removeback();
//l.push_front({k,v});
l.push_front(*node);
mp[k] = l.begin()
}
void movetohead(list<Node>::iterator arg, int new_val){
(*arg).value = new_val;
l.splice(l.begin(),l,arg);
mp[arg->key]= l.begin();
}
public:
LRUCache(int &cap){
cp = cap;
}
void set(int k,int v){
if (mp.find(k)!=mp.end()){
if (mp.size()>1)
movetohead(mp[k],v);
else
l.begin()->value = v;
}
else
addatfront(k,v);
}
int get (int k){
if (mp.find(k)!=mp.end())
return mp[k]->value;
return -1;
}
}typedef LRUCache;
int main()
{
int n, capacity,i;
cin>> n>> capacity;
LRUCache l(capacity);
for (i =0;i< n;i++){
string command;
cin>> command;
if (command == "get"){
int key;
cin >> key;
cout<< l.get(key)<< endl;
}
else if(command == "set"){
int key,value;
cin>> key>>value;
l.set(key, value);
}
}
return 0;
}
Input Test case 1:
3 1
set 1 2
get 1
get 2
Output:
2
-1
Input Test case 2:
22 4
set 7 1905
get 16
get 4
set 20 1738
get 14
set 12 320
set 4 1382
set 11 1049
set 8 1372
get 11
set 7 937
set 9 654
set 11 1727
get 1
set 13 1945
get 5
get 15
set 6 1668
set 8 270
set 1 604
get 20
get 5`
Output:
-1
-1
-1
1049
-1
-1
-1
1738
-1
In the actual output, I see -1 instead of 1738 for the second-to-last line of output.
struct Node { } typedef Node;}, the typedef should not be there. Also storing iterators for later use is not a good idea in general (lot of containers can invalidate iterators). Consider using a std::vector and store indices. C++ idiom, "it is almost always std::vector" (only use list if you have a lot of inserts at random places)20 -> 1738entry should have been thrown out of the cache long before it's looked up.std::listis?