LFU算法

本文详细介绍了一种LFU(Least Frequently Used)缓存算法的实现过程,使用C++编程语言,结合list和unordered_map数据结构,实现了缓存的获取和插入操作,同时处理了缓存容量限制和频繁度更新的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <list>
#include <unordered_map>
using namespace std;
class LFUCache {
public:
    LFUCache(int capacity) {
    	_capacity = capacity;
        _min_frequent = 1;
    }
    struct CacheNode
    {
    	int key;
    	int value;
    	int frequent;
    };
    //此函数刚开始没有抽象出来。因为没有理解LFU写入还有修改数据
    int& touch(list<CacheNode>::iterator itr){
       	CacheNode& node = *itr;
       	int old_frequent = node.frequent;
       	int new_frequent = ++node.frequent;
       	_cache[new_frequent].splice(_cache[new_frequent].begin(), _cache[old_frequent], itr);
       	//splice厉害 抵三句 _cache[frequent].push_front(node); _cache[frequent - 1].erase(itr); _map[itr->key] = _cache[new_frequent].begin();
       	if (_cache[old_frequent].size() == 0 && _min_frequent == old_frequent){
       		_min_frequent = new_frequent;
       	}
       	return itr->value;//begin返回iterator 与之对应的front()
    }
    int get(int key) {
    	auto itr = _map.find(key);//测试后发现find快于count,itr对应的是pair
        if (itr == _map.end()) {
        	return -1;
        }
       	return touch(itr->second);
    }
    void put(int key, int value) {
        if (_capacity == 0){
        	return;
        }
        //1.查询是否存在,存在更新数据
        auto itr = _map.find(key);
        if (itr != _map.end()){
        	touch(itr->second) = value;
        }else{
        	//2.删除多余节点,更新_min_frequent
        	if (_map.size() >= _capacity) {
        	    //cout <<"_min_frequent" <<_min_frequent <<endl;
	        	int key = _cache[_min_frequent].back().key;
				//cout <<"delete:" << _cache[_min_frequent].back().value << " frequent:" << _cache[_min_frequent].back().frequent << endl;
	        	_map.erase(key);
	        	_cache[_min_frequent].pop_back();
	        	if (_cache[_min_frequent].size() == 0 && _map.size() > 0){
	        		while (_cache[++_min_frequent].size() == 0);
	        	}
        	}
            //插入节点
        	CacheNode node{key, value, 1};
        	_cache[1].push_front(node);
        	_map[key] = _cache[1].begin();
        	_min_frequent = 1;
        }
    }
    size_t _capacity;
    int _min_frequent;
    unordered_map<int, list<CacheNode> > _cache;
    unordered_map<int, list<CacheNode>::iterator> _map;
};
int main() {
	LFUCache cache = *((LFUCache *) new LFUCache(3));
	cache.put(2, 2);
	cache.put(1, 1);
	cout << cache.get(2) <<endl;    
	cout << cache.get(1) <<endl;
	cout << cache.get(2) <<endl;  
	cache.put(3, 3);   
	cache.put(4, 4);  
	cout << cache.get(3) <<endl; 
	cout << cache.get(2) <<endl;
	cout << cache.get(1) <<endl;
	cout << cache.get(4) <<endl;
	return 0;
}

 

引用中提到,LFU(最少使用频率)缓存替换算法是一种常见的缓存替换算法。引用中提到,要理解LFU算法,首先要了解LRU(最近最少使用)算法,因为它们的原理类似。LFU算法和LRU算法都是用来管理缓存中的数据的替换策略。 LFU算法主要基于缓存中数据的使用频率来进行替换。每当缓存中的数据被访问时,其使用频率就会增加。当需要替换缓存中的数据时,LFU算法会选择使用频率最低的数据进行替换,即使用频率最低的数据很有可能是最不常用的数据。 与LFU算法类似,LRU算法是基于最近访问时间来进行替换。每当数据被访问,就会更新其最近访问时间。当需要替换数据时,LRU算法会选择最久未被访问的数据进行替换。 虽然LFU和LRU算法在实现上有一些差异,但它们都是为了优化缓存的性能。LFU算法主要关注数据的使用频率,而LRU算法则关注数据的最近访问时间。这些算法可以帮助我们更好地管理缓存中的数据,提高缓存的命中率和性能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [LFU缓存替换算法:least frequency unused 缓存替换算法](https://blog.csdn.net/weixin_46838716/article/details/124369765)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值