LFU-双hash字典实现

本文介绍了LFUCache,一种使用了LFU(LeastFrequentlyUsed,最少使用)策略的数据结构,当插入超过最大容量时,会删除频率最低的键值对。它包含私有成员如CacheNode、capacity、频率映射等,以及get和put方法来维护缓存的逻辑。

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

LFU c++11 实现,当插入数值数量超过最大容量时,同样频率删除最久未使用的key

template <typename key_t, typename value_t>
class LFUCache {
private:
    struct CacheNode {
        key_t key;
        value_t value;
        int frequency;
    };

    std::size_t _capacity;
    std::unordered_map<key_t, typename std::list<CacheNode>::iterator> _cache; // key:frequency
    std::unordered_map<int, std::list<CacheNode>> _frequency; // frequency:cacheNode
    int _minFrequency; // 当前最小的访问频率

public:
    LFUCache(std::size_t capacity) {
        _capacity = capacity;
        _minFrequency = 0;
    }

    key_t get(key_t key) {
        auto iter = _cache.find(key);
        if (iter == _cache.end()) {
            throw std::logic_error("can not found the key!");
        }
        auto &cacheNodeIter = iter->second;
        // update _frequency
        auto oldFrequency = cacheNodeIter->frequency;
        cacheNodeIter->frequency += 1;
        _frequency[oldFrequency + 1].splice(_frequency[oldFrequency + 1].end(), _frequency[oldFrequency], cacheNodeIter);
        if( _frequency[oldFrequency].empty()){
            _frequency.erase(oldFrequency);
        }

        // update _minFrequency
        if (_frequency[_minFrequency].empty() && _minFrequency == oldFrequency) {
            _minFrequency = oldFrequency + 1;
        }

        return cacheNodeIter->value;
    }

    void put(key_t key, value_t value) {
        if (_capacity <= 0) {
            throw std::logic_error("capacity is zero!");
        }

        auto iter = _cache.find(key);
        if (iter == _cache.end()) { // 不存在
            if (_cache.size() >= _capacity) {
                auto &node = _frequency[_minFrequency].front();
                _cache.erase(node.key);
                _frequency[_minFrequency].pop_front();
            }

            _frequency[1].push_back({key, value, 1});
            _cache.emplace(key, std::prev(_frequency[1].end()));
            _minFrequency = 1;
        } else { // 存在
            get(key); // 更新计数
            iter->second->value = value; // 更新值
        }
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值