LFU算法:(Least Frequently Used),对每一个数据的访问频次作一记录,数据的访问次数越多,节点访问次数越大。
*新插入的数据访问频次为1;
*相同频次的数据按时间排序,后插入的在前面;
*当需要淘汰数据时,会从尾部开始淘汰,即访问频次从小到大
#include<iostream>
#include<unordered_map>
using namespace std;
class LFUCache
{
public:
LFUCache(int cap):capacity(cap),size(0){}
int get(int key)
{
if(m.count(key)==0) return -1;
//get使得fre+1,将原来fre对应的节点删除,插入到fre+1的list中
hash_fre[m[key].second].erase(hash_node[key]);
m[key].second++;
hash_fre[m[key].second].push_back(key);
hash_node[key]=--hash_fre[m[key].second].end();
if(hash_fre[min_fre].size()==0) min_fre++;
return m[key].first;
}
void put(int key,int value)
{
if(capacity<=0) return;
if(get(key)!=-1)
{
m[key].first=value;
return;
}
//容量已满,删除最不常用的key
if(size>=capacity)
{
m.erase(hash_fre[min_fre].front());
hash_node.erase(hash_fre[min_fre].front());
hash_fre[min_fre].pop_front();
}
//插入key
m[key]={value,1};
hash_fre[1].push_back(key);
hash_node[key]=--hash_fre[1].end();
min_fre=1;
if(size<cap) size++;
}
private:
int capacity;//缓存容量
int size;//当前缓存大小
int min_fre;//最小访问频率
unordered_map<int,pair<int,int>> m;//key与{value,fre}之间的映射
unordered_map<int,list<int>> hash_fre;//fre与list之间的映射(节点为key)
unordered_map<int,list<int>::iterator> hash_node;//key与list节点之间的映射
};