LRUCache的C++实现
LRUCache可以用于在内存中保持当前的热点数据,下面实现一个有大小限制的lru cache,相关如下:
1. 模板化;
2. 利用std::unordered_map实现o(1)查找,利用std::list实现o(1)删除 (双链表+hash表);
3. 用map保持key和结点在链表中的位置(iterator)
4. 需要同时考虑如下情况:
put操作:
(1) 如果当前key存在,则将对于的结点剪切到链表的头部,同时更新哈希表中value的值;
(2) 如果当前key不存在于hash表中,且元素个数已经达到最大值,则删除链表的最后一个结点,同时把新结点插入到链表的头部,同时更新hash表(增加新节点和删除旧结点表项);
get操作:
(1)检查当前hash表中是否有该key,如果存在,则将该key对应的结点move到list的头部,并同步更新map的value;
(2)如果hash表中不存在改key,则返回-1;
对应的代码如下:
#include <iostream>
#include <unordered_map>
#include <list>
#include <string>
#include <utility>template<class KeyType, class ValueType>
class LRUCache {
public:LRUCache(int capacity) : m_capacity(capacity) {} int get(KeyType key, ValueType& value);//0-找到, -1-没找到int put(KeyType key, ValueType value);// 0-插入成功, -1 -插入失败void show() const; //展示当前LRUcache中的内容
private:typedef std::pair<KeyType, ValueType> Node;typedef typename std::list<Node>::iterator Iter;std::list<Node> m_list;//双向链表std::unordered_map<KeyType, Iter> m_map;//哈希表int m_capacity;//cache的最大元素个数
}; template<class KeyType, class ValueType>
int LRUCache<KeyType, ValueType>::get(KeyType key, ValueType& value) {if (m_map.count(key) <= 0) {return -1; } //获取值Iter iter = m_map[key];//将值移到headm_list.splice(m_list.begin(), m_list, iter);return 0;
}template<class KeyType, class ValueType>
int LRUCache<KeyType, ValueType>::put(KeyType key, ValueType value) {//检查当前map中是否有该key,如果存在,则将该key对应的结点move到list的头部,并同步更新map的valueif (m_map.count(key) > 0) {Iter iter = m_map[key];iter->second = value; //充值map中key对应的valuem_list.splice(m_list.begin(), m_list, iter); //将对应的结点move到header} else {//检查当前元素是否达到容器的最大值,如果达到了阈值,则先将最后一个元素删除,将新元素插入到首部,同时更新mapNode node(key, value);if (m_list.size() == m_capacity) {m_map.erase(m_list.back().first);//将元素从map中删除m_list.pop_back();//移除最后一个元素} //将新元素插入到map和list中m_list.push_front(node);m_map[key] = m_list.begin();} return 0;
}template<class KeyType, class ValueType>
void LRUCache<KeyType, ValueType>::show() const {auto iter = m_list.begin(); auto iter_end = m_list.end();while (iter != iter_end) {std::cout << "(" << iter->first << "," << iter->second << ") ";iter++;}std::cout << std::endl;
}int main(int argc, char* argv[]) {LRUCache<std::string, int> cache(5);//先插入4个元素std::cout << "insert (aaa,111) (bbb,222) (ccc,333) (ddd,444) (eee,555)" << std::endl;cache.put("aaa", 111);cache.put("bbb", 222);cache.put("ccc", 333);cache.put("ddd", 444);cache.put("eee", 555);cache.show();//访问元素cccint result = 0;cache.get("ccc", result);std::cout << "after visit ccc" << std::endl;cache.show();//再插入一个元素("fff",666)cache.put("fff", 666);std::cout << "insert (fff,666)" << std::endl;cache.show();return 0;
}
输出结果如下:
insert (aaa,111) (bbb,222) (ccc,333) (ddd,444) (eee,555)
(eee,555) (ddd,444) (ccc,333) (bbb,222) (aaa,111)
after visit ccc
(ccc,333) (eee,555) (ddd,444) (bbb,222) (aaa,111)
insert (fff,666)
(fff,666) (ccc,333) (eee,555) (ddd,444) (bbb,222)
LRUCache的C++实现相关推荐
- 内存缓存LruCache的简单使用
LruCache算法(Least Recently Used),也叫近期最少使用算法. 这个类非常适合用来缓存图片,它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,并 ...
- Android 图片缓存之内存缓存技术LruCache,软引用
Android 图片缓存之内存缓存技术LruCache,软引用
- 关于 npm 中 lru-cache 之 maxAge 盲点 源码分析
下面copy了一段实例 var LRU = require("lru-cache") , options = { max: 500 , length: function (n, k ...
- Android LruCache 压缩图片 有效避免程序OOM
压缩加载大图片 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状.不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小.比如说系统图片库里展示的图片大都是 ...
- LruCache缓存处理及异步加载图片类的封装
Android中的缓存处理及异步加载图片类的封装 一.缓存介绍: (一).Android中缓存的必要性: 智能手机的缓存管理应用非常的普遍和需要,是提高用户体验的有效手段之一. 1.没有缓存的弊端 ...
- 图片缓存之内存缓存技术LruCache,软引用
图片缓存之内存缓存技术LruCache,软引用 每当碰到一些大图片的时候,我们如果不对图片进行处理就会报OOM异常, 这个 问题曾经让我觉得很烦恼 ,后来终于得到了解决, 那么现在就让我和大家一起分享 ...
- LruCache 源码解析
前言: 没看懂LruCache之前,我擦, LruCache这个类设计有啥意义? LinkedHashMap 完全可以代替.看懂之后,设计的真好. LruCache 概念描述 一般来说,缓存策略主要包 ...
- LruCache原理
创建LruCache对象,重写其中的sizeOf方法: 然后看看LruCache内部长啥样子??? 看到A处,这里有个LinkedHashMap,这个是专门来存要缓存的对象,这个数据结构有个特点即链表 ...
- [置顶] 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅
转载请注明出处http://blog.csdn.net/xiaanming/article/details/9825113 异步加载图片的例子,网上也比较多,大部分用了HashMap<Strin ...
- LruCache缓存机制
LruCache: Android提供的使用了(Least Recently Used)近期最少使用算法的缓存类 内部基于LinkedHashMap实现 实现这个主要需要重写 构造时需要确定Cache ...
最新文章
- 2022-2028年中国车载天线行业市场前瞻与投资战略规划分析报告
- 2023 USNews全美计算机研究生院排名发布!MIT、CMU分别称霸总榜和AI分榜
- 10多所高校发布通知: 今年研究生复试或有变!
- 【Python】5个方便好用的Python自动化脚本
- Python多线程(自学必备 超详细)
- 8999元起!vivo X Fold折叠屏旗舰今日首销:采用航天级浮翼式铰链
- Linux 硬中断和软中断
- Spring Cloud 中的@FeignClient注解
- Python:暴力破解密码
- 延迟队列DelayQueue原理
- 从SHAttered事件谈安全
- Web爬虫|入门教程之爬虫简介
- 二分法(Bisection)求解单根(python,数值积分)
- 个人财务管理系统beancount-gs
- 安卓+ios系统--手机端页面自适应手机屏幕大小,禁止手动放大和缩小VUE
- python绘制拟合回归散点图_matplotlib中散点图的回归线和拟合曲线
- Blender 利用遮罩剔除顶点
- 生成Android平台签名证书(.keystore)
- Matlab怎么计算信号的能量,学习用Matlab计算离散信号的功率和能量.PPT
- html 指定 favicon,favicon 不只是个图标
热门文章
- ExecutorUtil
- Learning to Rank(以下简称L2R)
- LightWave 3D 2019 for Mac(三维动画制作软件)
- 各行各业数据及分析研究报告网站参考
- android 陀螺仪源码,陀螺仪源码 android
- 共振峰估计2MATLAB
- 《算法第一步》出版啦!
- sublime text 打开总是弹框报错Unable to download XXX. Please view the console for more details.解决办法
- c语言利用rand()函数生成一组不重复的随机数
- Gmail附件大小及格式限制全面解析