传送门

此题让我们实现一个LRU的模板类。本题较简便且高效的写法是维护一个std::list和一个std::unordered_map

std::list 与 std::unordered_map 中存放的内容

std::list中存放各key,类型为K。链表中各键码存放的顺序是按照访问顺序存放的

std::unordered_map中以key为第一维,第二维为一个pair,其firstsecond分别为:

first: 该key对应的value。

second:该key在std::list中的迭代器方便访问。

为方便,下面用“链表”来指代std::list,用“哈希表”来指代std::unordered_map

各操作实现

insert操作:用哈希表判断该键是否已经存在。若存在,先在链表中删除该key,然后再新加一个该key到链表尾部,并更新在哈希表中的value和链表的迭代器。若不存在,则直接加至链表尾部,并在哈希表中插入该key,伴随着对应的value和链表迭代器。

get操作:直接从哈希表中获得其value即可。代码实现未检测该key是否存在,严谨来说应该加上异常处理。

contains操作:直接在哈希表中查询是否存在该key即可。

vis操作:用哈希表判断该键是否存在。若不存在,则本操作无效。否则,将该键从链表中删除,然后再将其加至链表尾部,并更新哈希表中对应链表迭代器。

pop操作:判断是否整个容器已经为空。若为空,则本操作无效。否则,将链表头部元素从链表中删除,并在哈希表中删除对应键值信息。

remove操作:用哈希表判断该键是否存在。若不存在,则本操作无效。否则,将该键从链表中删除,并在哈希表中删除对应键值信息。

empty操作:哈希表或链表判空即可。

size操作:取哈希表或链表大小即可。

clear操作:清空哈希表和链表即可。

时间复杂度

各操作基于对链表和哈希表的修改。期望复杂度均为\(O(1)\)。

参考代码实现

  1. #include <list>
  2. #include <unordered_map>
  3. template <typename K, typename V>
  4. class LRU {
  5. private:
  6. typedef typename std::list<K>::iterator listIter;
  7. typedef typename std::unordered_map<K, std::pair<V, listIter>>::iterator unorderedMapIter;
  8. std::list<K> lst;
  9. std::unordered_map<K, std::pair<V, listIter>> mp;
  10. public:
  11. void insert(const K &key, const V &value) {
  12. unorderedMapIter it = mp.find(key);
  13. if (it == mp.end()) {
  14. lst.emplace_back(key);
  15. mp.insert(std::make_pair(key, std::make_pair(value, --lst.end())));
  16. } else {
  17. lst.erase(it->second.second);
  18. lst.emplace_back(key);
  19. it->second = std::make_pair(value, --lst.end());
  20. }
  21. }
  22. // If Key doesn't exist, this will create one <Key, zero>
  23. V get(const K &key) {
  24. return mp[key].first;
  25. }
  26. bool contains(const K &key) {
  27. return mp.count(key) == 1;
  28. }
  29. void vis(const K &key) {
  30. unorderedMapIter it = mp.find(key);
  31. if (it != mp.end()) {
  32. lst.erase(it->second.second);
  33. lst.emplace_back(key);
  34. it->second.second = --lst.end();
  35. }
  36. }
  37. void pop() {
  38. if (!lst.empty()) {
  39. mp.erase(lst.front());
  40. lst.pop_front();
  41. }
  42. }
  43. void remove(const K &key) {
  44. unorderedMapIter it = mp.find(key);
  45. if (it != mp.end()) {
  46. lst.erase(it->second.second);
  47. mp.erase(it);
  48. }
  49. }
  50. bool emtpy() { // 注意本题要求函数名为emtpy
  51. return lst.empty();
  52. }
  53. unsigned long long size() {
  54. return lst.size();
  55. }
  56. void clear() {
  57. lst.clear();
  58. mp.clear();
  59. }
  60. };

FJUTOJ-3682 LRU算法的实现2 (链表+哈希)的更多相关文章

  1. java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现

    java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析 ...

  2. [整理] LRU 算法的实现方式

    目录 概念 方法选择 实现方案(基于LinkedHashMap) 改进方案 1.LRU-K 2.Two queue 3.Multi Queue(MQ) LRU类算法对比 LRU 在 Redis 中的应 ...

  3. linkedhashmap中关于LRU算法的实现

    //LinkedHashMap的一个构造函数,当参数accessOrder为true时,即会按照访问顺序排序,最近访问的放在最前,最早访问的放在后面 public LinkedHashMap(int ...

  4. Python学习(三) 八大排序算法的实现(下)

    本文Python实现了插入排序.基数排序.希尔排序.冒泡排序.高速排序.直接选择排序.堆排序.归并排序的后面四种. 上篇:Python学习(三) 八大排序算法的实现(上) 1.高速排序 描写叙述 通过 ...

  5. Bug2算法的实现(RobotBASIC环境中仿真)

    移动机器人智能的一个重要标志就是自主导航,而实现机器人自主导航有个基本要求--避障.之前简单介绍过Bug避障算法,但仅仅了解大致理论而不亲自动手实现一遍很难有深刻的印象,只能说似懂非懂.我不是天才,不 ...

  6. Canny边缘检测算法的实现

    图像边缘信息主要集中在高频段,通常说图像锐化或检测边缘,实质就是高频滤波.我们知道微分运算是求信号的变化率,具有加强高频分量的作用.在空域运算中来说,对图像的锐化就是计算微分.由于数字图像的离散信号, ...

  7. SSE图像算法优化系列十三:超高速BoxBlur算法的实现和优化(Opencv的速度的五倍)

    在SSE图像算法优化系列五:超高速指数模糊算法的实现和优化(10000*10000在100ms左右实现) 一文中,我曾经说过优化后的ExpBlur比BoxBlur还要快,那个时候我比较的BoxBlur ...

  8. 详解Linux内核红黑树算法的实现

    转自:https://blog.csdn.net/npy_lp/article/details/7420689 内核源码:linux-2.6.38.8.tar.bz2 关于二叉查找树的概念请参考博文& ...

  9. 详细MATLAB 中BP神经网络算法的实现

    MATLAB 中BP神经网络算法的实现 BP神经网络算法提供了一种普遍并且实用的方法从样例中学习值为实数.离散值或者向量的函数,这里就简单介绍一下如何用MATLAB编程实现该算法. 具体步骤   这里 ...

随机推荐

  1. Java软件工程师技能图谱

    原文链接:Java软件工程师技能图谱 最近在考虑"拥有怎样的技能才能算一名合格的java软件工程师呢?"这个问题.碰巧在github发现一个很棒的开源项目--程序员技能图谱.@Zh ...

  2. 【转载】structlog4j介绍

    源文章:structlog4j介绍 结构化日志对于日志的收集的作用挺大的,根据自身的业务场景,基于SLF4J实现了structlog4j. 相关引用 Gradle // 基础包 compile 'te ...

  3. 利用ARP欺骗进行MITM(中间人攻击)

    ARP欺骗主要骑着信息收集得作用,比如可以利用欺骗获取对方流量,从流量分析你认为重要得信息 0X01  了解ARP Arp协议 ARP(Address Resolution Protocol,地址解析 ...

  4. AI Web 1.0

    kali:192.168.0.103 目标机:192.168.0.105 0X01 端口和目录扫描 打开目标主页没有任何信息 a) 端口扫描 只有一个80端口开启 b) 目录扫描 0x03 查看敏感目 ...

  5. 0.5 Linux的联通性命令汇总

    linux下网络端口连通性测试命令汇总 一.telnet ip port 1.1 安装: 安装telnet服务 [centos.ubuntu]安装telnet命令的方法.] yum list teln ...

  6. CF #622 div.2

    序 ~ieowjf~~ 真的只有老邱在支持我吗(雾 #622 T1 此题做法显然,但是,不知为何,就是会评测机有小问题...无语 上 SingerCoder 的码,不知为何,我的码风总是毒瘤 #inc ...

  7. 爬取漫画DB上的《浪客行》

    漫画链接:https://www.manhuadb.com/manhua/324 建议:早上爬,速度较快. 天下无双宫本武藏 代码 # https://www.manhuadb.com/manhua/ ...

  8. 基于90nm CMOS技术的功能齐全的64Mb DDR3 STT-MRAM

    自旋转矩磁阻随机存取存储器(ST-MRAM)有望成为一种快速,高密度的非易失性存储器,可以增强各种应用程序的性能,特别是在用作数据存储中的非易失性缓冲器时设备和系统.为此,everspin开发了基于9 ...

  9. JAVA成长之路SpringCloud脚印(一)

    从即日起开始学习SpringCloud,在这里记录下学习过程,共勉,欢迎指正. 环境:IDEA2019.3.3.JAVA13 一.spring cloud简介 spring cloud 为开发人员提供 ...

  10. 使用FRP做内网穿透

    Github地址:https://github.com/fatedier/frp 什么是FRP? frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp 协议,为 http 和 h ...