最不常用 (LFU)是一种缓存算法,其中,只要缓存溢出,就会删除最不常用的缓存块。在 LFU 中,我们检查旧页面以及该页面的频率,如果页面的频率大于旧页面,我们无法删除它,如果所有旧页面都具有相同的频率,则采用 last ie FIFO 方法并删除该页面。
最小堆数据结构是实现该算法的一个很好的选择,因为它以对数时间复杂度处理插入、删除和更新。可以通过删除最近最少使用的缓存块来解决平局。已经使用了以下两个容器来解决问题:
- 一个整数对向量被用来表示缓存,其中每对由块号和它被使用的次数组成。该向量以最小堆的形式排序,这允许我们在恒定时间内访问最不常用的块。
- 哈希图已用于存储缓存块的索引,允许在恒定时间内进行搜索。
下面是上述方法的实现:
// C++ program for LFU cache implementation
#include
using namespace std;
// Generic function to swap two pairs
void swap(pair& a, pair& b)
{
pair temp = a;
a = b;
b = temp;
}
// Returns the index of the parent node
inline int parent(int i)
{
return (i - 1) / 2;
}
// Returns the index of the left child node
inline int left(int i)
{
return 2 * i + 1;
}
// Returns the index of the right child node
inline int right(int i)
{
return 2 * i + 2;
}
// Self made heap tp Rearranges
// the nodes in order to maintain the heap property
void heapify(vector >& v,
unordered_map& m, int i, int n)
{
int l = left(i), r = right(i), minim;
if (l < n)
minim = ((v[i].second < v[l].second) ? i : l);
else
minim = i;
if (r < n)
minim = ((v[minim].second < v[r].second) ? minim : r);
if (minim != i) {
m[v[minim].first] = i;
m[v[i].first] = minim;
swap(v[minim], v[i]);
heapify(v, m, minim, n);
}
}
// Function to Increment the frequency
// of a node and rearranges the heap
void increment(vector >& v,
unordered_map& m, int i, int n)
{
++v[i].second;
heapify(v, m, i, n);
}
// Function to Insert a new node in the heap
void insert(vector >& v,
unordered_map& m, int value, int& n)
{
if (n == v.size()) {
m.erase(v[0].first);
cout << "Cache block " << v[0].first
<< " removed.\n";
v[0] = v[--n];
heapify(v, m, 0, n);
}
v[n++] = make_pair(value, 1);
m.insert(make_pair(value, n - 1));
int i = n - 1;
// Insert a node in the heap by swapping elements
while (i && v[parent(i)].second > v[i].second) {
m[v[i].first] = parent(i);
m[v[parent(i)].first] = i;
swap(v[i], v[parent(i)]);
i = parent(i);
}
cout << "Cache block " << value << " inserted.\n";
}
// Function to refer to the block value in the cache
void refer(vector >& cache, unordered_map& indices, int value, int& cache_size)
{
if (indices.find(value) == indices.end())
insert(cache, indices, value, cache_size);
else
increment(cache, indices, indices[value], cache_size);
}
// Driver Code
int main()
{
int cache_max_size = 4, cache_size = 0;
vector > cache(cache_max_size);
unordered_map indices;
refer(cache, indices, 1, cache_size);
refer(cache, indices, 2, cache_size);
refer(cache, indices, 1, cache_size);
refer(cache, indices, 3, cache_size);
refer(cache, indices, 2, cache_size);
refer(cache, indices, 4, cache_size);
refer(cache, indices, 5, cache_size);
return 0;
}
输出:
Cache block 1 inserted.
Cache block 2 inserted.
Cache block 3 inserted.
Cache block 4 inserted.
Cache block 3 removed.
Cache block 5 inserted.
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。