LRU和LFU算法的简单实现

LRU

#include <iostream>
#include <unordered_map>
#include <list>
struct Node{int key;int value;Node(int key, int value):key(key),value(value){}
};
class LruCache{
private:int maxCapacity;// 最大容量std::list<Node>CacheList;// 缓存链表std::unordered_map<int, std::list<Node>::iterator>mp; // 快速找到key在链表中位置
public:LruCache(int cap):maxCapacity(cap){}int get(int key){// 找一个缓存是否在缓存链表中if(mp.find(key) == mp.end()){return -1;}auto cur = mp[key];CacheList.splice(CacheList.begin(), CacheList, cur);return cur->value;}void put(int key, int value){// 往缓存中插入一个Nodeif(mp.find(key) != mp.end()){ // key 存在时候auto cur = mp[key];cur->value = value;CacheList.splice(CacheList.begin(), CacheList, cur);return;}if(CacheList.size() == maxCapacity){// key 不存在的时候村缓存满的时候需要将CacheList中队尾的一个弹出去auto last = CacheList.back();mp.erase(last.key);CacheList.pop_back();}CacheList.insert(CacheList.begin(), Node(key, value));mp[key] = CacheList.begin();      }};
int main(){LruCache cache(3);cache.put(1, 1);cache.put(2, 2);std::cout << cache.get(1) << std::endl; // 1cache.put(3, 3);std::cout << cache.get(2) << std::endl; // -1cache.put(4, 4); std::cout << cache.get(1) << std::endl; // -1std::cout << cache.get(3) << std::endl; // 3std::cout << cache.get(4) << std::endl; // 4std::getchar();return 0;
}

LFU

#include <iostream>
#include <unordered_map>
#include <vector>
#include <queue>
#include <algorithm>
struct CacheNode{int key;int value;int freq;// 频率CacheNode() = default;CacheNode(int key, int value, int freq):key(key),value(value),freq(freq){}bool operator < (const CacheNode& other)const{return this->freq > other.freq;}
};
class LfuCache{
public:int maxCapacity;// 维护一个key到CacheNode的一个映射std::unordered_map<int, CacheNode>keymap;// 维护一个freq到CacheNode的一个映射std::unordered_map<int, std::vector<CacheNode>>freqmap;// 维护频率的最小堆std::priority_queue<CacheNode, std::vector<CacheNode>>minheap;
public: LfuCache(int cap):maxCapacity(cap){}int get(int key){if(keymap.find(key) == keymap.end()){return -1;}auto cur = keymap[key];updateFreq(cur);return cur.value;}void put(int key, int value){if(keymap.find(key) != keymap.end()){// key存在auto cur = keymap[key];cur.value = value;updateFreq(cur);return ;}if(keymap.size() == maxCapacity){// 满了       // 删除最小频率的键CacheNode node = minheap.top();minheap.pop();freqmap[node.freq].erase(std::remove_if(freqmap[node.freq].end(),freqmap[node.freq].end(),[&](const CacheNode cur){return cur.key == node.key;}),freqmap[node.freq].end());keymap.erase(node.key);}// 插入新的键值对CacheNode node(key, value, 1);keymap[key] = node;minheap.push(node);freqmap[1].push_back(node);}// 更新缓存记录频率void updateFreq(CacheNode node) {// 从原频率表删去freqmap[node.freq].erase(std::remove_if(freqmap[node.freq].end(),freqmap[node.freq].end(),[&](const CacheNode cur){return cur.key == node.key;}),freqmap[node.freq].end());// 更新频率++node.freq;// 插入到新频率表freqmap[node.freq].push_back(node);// 更新最小堆先要将之前堆中的Node删除std::priority_queue<CacheNode, std::vector<CacheNode>>tmp;while(!minheap.empty()){auto cur = minheap.top();minheap.pop();if(cur.key != node.key){tmp.push(cur);}}minheap.swap(tmp);minheap.push(node);}
};
int main(){LfuCache cache(3);std::cout<<cache.get(1)<<std::endl;cache.put(1,1);cache.put(2,2);cache.put(3,3);cache.get(1);cache.get(2);cache.put(4,4);std::cout<<cache.minheap.size()<<std::endl;while(!cache.minheap.empty()){auto cur = cache.minheap.top();cache.minheap.pop();std::cout<<cur.key<<cur.value<<cur.freq<<std::endl;}std::getchar();
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/60556.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

修改linux中tomcat的端口

随便修改一个 以8055为例子 开放8081端口 firewall-cmd --permanent --add-port8081/tcp firewall-cmd --reload firewall-cmd --list-all

Linux中的dpkg指令(dpkg -l | grep XXX等)

dpkg是Debian包管理系统中的一个工具&#xff0c;用于在Linux系统中安装、升级、删除和管理软件包。它是Debian、Ubuntu以及基于它们的发行版中的包管理器。 dpkg 有很多用法&#xff0c;常用之举例:dpkg -l | grep apt 显示系统中安装的与apt相关&#xff08;命名&#xff09…

Android 蓝牙开发( 二 )

前言 上一篇文章给大家分享了Android蓝牙的基础知识和基础用法&#xff0c;不过上一篇都是一些零散碎片化的程序&#xff0c;这一篇给大家分享Android蓝牙开发实战项目的初步使用 效果演示 : Android蓝牙搜索&#xff0c;配对&#xff0c;连接&#xff0c;通信 Android蓝牙实…

模拟实现应用层协议

模拟实现应用层协议 文章目录 模拟实现应用层协议应用层再谈协议 序列化和反序列化 网络版计算器自定义协议利用Json进行序列化和反序列化json库的安装条件编译 应用层 应用层&#xff08;Application layer&#xff09;是OSI模型的第七层。应用层直接和应用程序接口并提供常见…

在 WSL2 中使用 NVIDIA Docker 进行全栈开发和深度学习 TensorFlow pytorch GPU 加速

在 WSL2 中使用 NVIDIA Docker 进行全栈开发和深度学习 TensorFlow pytorch GPU 加速 0. 背景 0.1 起源 生产环境都是在 k8d pod 中运行&#xff0c;直接在容器中开发不好嘛&#xff1f;每次换电脑&#xff0c;都要配配配&#xff0c;呸呸呸新电脑只安装日常用的软件不好嘛&…

JVM虚拟机篇

JVM虚拟机篇 JVM介绍、运行流程 面试官&#xff1a; JVM由那些部分组成&#xff0c;运行流程是什么&#xff1f; 候选人&#xff1a; 嗯&#xff0c;好的~~ 在JVM中共有四大部分&#xff0c;分别是ClassLoader&#xff08;类加载器&#xff09;、Runtime Data Area&#x…

INDEMIND:“大+小”多机协同,实现机器人商用场景全覆盖

随着商用清洁机器人进入越来越多的场景中&#xff0c;单一的中型机器人并不能有效覆盖所有区域&#xff0c;更加细分化的产品组合正在成为新的趋势。 产品形态的“新趋势” 在商用场景中&#xff0c;目前的商用清洁机器人几乎均是中大型的产品形态&#xff0c;较大的体型意味…

视频汇聚/视频云存储/视频监控管理平台EasyCVR新增首次登录强制修改密码

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。视频汇聚平台既具…

如何在 JavaScript 中查看结构体数组?

调试 JavaScript 代码的最简单方法是使用许多开发人员使用的 console.log()。有时&#xff0c;我们需要了解数组的结构和存储的值以进行调试。以下介绍如何查看结构数组。 JavaScript 的各种方法允许我们检查数组的结构。例如&#xff0c;我们可以知道数组是否包含对象、嵌套数…

[JDK8下的HashMap类应用及源码分析] 数据结构、哈希碰撞、链表变红黑树

系列文章目录 [Java基础] StringBuffer 和 StringBuilder 类应用及源码分析 [Java基础] 数组应用及源码分析 [Java基础] String&#xff0c;分析内存地址&#xff0c;源码 [JDK8环境下的HashMap类应用及源码分析] 第一篇 空构造函数初始化 [JDK8环境下的HashMap类应用及源码分…

Vue3列表竖向滚动(包含使用swiper的翻页效果)

一、使用element-plus表格进行滚动&#xff1a; 可以满足的需求&#xff1a;表格一行一行竖向滚动&#xff0c;类似走马灯。 不能满足的需求&#xff1a;表格分页竖向滚动&#xff0c;有翻页的效果。 代码&#xff1a; <template><el-table:data"tableData"…

Redis——》Redis的部署方式对分布式锁的影响

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

Java常见的排序算法

排序分为内部排序和外部排序&#xff08;外部存储&#xff09; 常见的七大排序&#xff0c;这些都是内部排序 。 1、插入排序&#xff1a;直接插入排序 1、插入排序&#xff1a;每次将一个待排序的记录&#xff0c;按其关键字的大小插入到前面已排序好的记录序列 中的适当位置…

ChatGPT AIGC 一个指令总结Python所有知识点

在ChatGPT中,直接输入一个指令就可以生成Python的所有知识点大纲。 非常实用的ChatGPT功能。 AIGC ChatGPT ,BI商业智能, 可视化Tableau, PowerBI, FineReport, 数据库Mysql Oracle, Office, Python ,ETL Excel 2021 实操,函数,图表,大屏可视化 案例实战 http://t.…

Angular中使用drag and drop实现文件拖拽上传,及flask后端接收

效果&#xff1a;拖拽文件到组件上面时 边框变大变红 松手后发送到服务器(或者点击蓝字手动选择文件)并且把文件名显示在框内&#xff0c;美化还没做 html <div class"drapBox"><div id"drop" (dragenter)"dragenter($event)" (dragov…

leetcode做题笔记105. 从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 思路一&#xff1a;递归 struct TreeNode* buildTree(int* preorder, int preorderSize, int* ino…

redis 应用 4: HyperLogLog

我们先思考一个常见的业务问题&#xff1a;如果你负责开发维护一个大型的网站&#xff0c;有一天老板找产品经理要网站每个网页每天的 UV 数据&#xff0c;然后让你来开发这个统计模块&#xff0c;你会如何实现&#xff1f; img 如果统计 PV 那非常好办&#xff0c;给每个网页一…

后台管理系统:项目路由搭建与品牌管理

路由的搭建 先删除一些不需要的界面 然后发现跑不起来&#xff0c;我们需要去配置 删减成这样&#xff0c;然后自己新建需要的路由组件 改成这样&#xff0c;这里要注意。我们是在layout这个大的组件下面的&#xff0c;meta 中的title就是我们侧边栏的标题&#xff0c;icon可…

Java eight 解读流(Stream)、文件(File)、IO和异常处理的使用方法

目录 Java 流(Stream)、文件(File)和IO读取控制台输入读写文件FileInputStreamFileOutputStream Java目录 Java 异常处理 Java 流(Stream)、文件(File)和IO java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。 Java.io 包中的流支持很多种…

51页企业数字化转型战略实践与启示PPT(附400份转型资料)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除&#xff0c;更多内容浏览公众号&#xff1a;智慧方案文库 企业数字化转型之路.pptx企业数字化转型大数据湖一体化平台项目建设方案PPT.pptx企业数字化转型大数据湖一体化运营管…