文件缓存系统LFU实现(华为OD)

不够完美,node里面的iterator迭代器可以怎么替换掉最好

#include <iostream>
#include <list>
#include <unordered_map>
#include <vector>
#include <algorithm>

using namespace std;

struct node{
    string key;
    int size;
    int freq;
    list<node>::iterator it;
    node(string k,int s,int f):key(std::move(k)),size(s),freq(f){}
};

class LFUCache{
private:
    int minFreq,capacity;
    unordered_map<string,node*> keyMap;
    unordered_map<int,list<node>> freqMap;
    void UpdateFreq(node* node){
        // 删除原始表的频率链表中的结点
        freqMap[node->freq].erase(node->it);
        // 频率链表空则删除链表
        if (freqMap[node->freq].empty()){
            freqMap.erase(node->freq);
            if (node->freq == minFreq) minFreq++;
        }
        // 插入到新频率链表中的结点
        node->freq++;
        freqMap[node->freq].push_front(*node);
        // 更新键表对应结点的链表指针
        node->it = freqMap[node->freq].begin();
    }
public:
    void InitialCache(int cap){
        capacity = cap;
        minFreq = 0;
        keyMap.clear();
        freqMap.clear();
    }
    void Get(const string &key){
        auto it = keyMap.find(key);
        if (it==keyMap.end()) return;
        UpdateFreq(it->second);
    }
    void Put(const string &key,int size){
        auto it = keyMap.find(key);
        if (it==keyMap.end()){
            // 如果缓存已满,需要删除最少使用且最旧使用的结点
            while (size > capacity && !freqMap.empty()){
                // 删除最低频率链表末尾结点
                node reNode = freqMap[minFreq].back();
                freqMap[minFreq].pop_back();
                // 更新缓存容量
                capacity += reNode.size;
                // 删除键表结点
                keyMap.erase(reNode.key);
                if (freqMap[minFreq].empty()){
                    freqMap.erase(minFreq);
                    // 找到下一个最小频率的频率链表
                    if (freqMap.empty()) minFreq = 1;
                    else{
                        while (freqMap.find(minFreq) == freqMap.end()) minFreq++;
                    }
                }
            }
            // 当容量足够时才能插入
            if (size <= capacity){
                // 插入新结点
                node* newNode = new node(key,size,1);
                minFreq = 1;
                freqMap[minFreq].push_front(*newNode);
                newNode->it = freqMap[minFreq].begin();
                keyMap[key] = newNode;
                capacity -= size;
            }
        } else{
            // 键已存在,更新频率
            UpdateFreq(it->second);
        }
        return;
    }
    vector<string> checkCache(){
        vector<string> res;
        for (auto it:keyMap) {
            res.push_back(it.first);
        }
        // 按字母排序
        sort(res.begin(), res.end());
        return res;
    }
};

int main(){
    int m,n;
    while (cin>>m>>n){
        string op,fn;
        int fs;
        LFUCache cache;
        cache.InitialCache(m);
        for (int i = 0; i < n; ++i) {
            cin>>op>>fn;
            if (op=="put") {
                cin>>fs;
                cache.Put(fn,fs);
            } else{
                cache.Get(fn);
            }
        }
        vector<string> res = cache.checkCache();
        if (res.empty()) cout<<"NONE"<<endl;
        else {
            string ans;
            for (string r:res) {
                ans += r + ',';
            }
            cout<<ans.substr(0,ans.size()-1)<<endl;
        }
    }

    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值