FJUTOJ-3682 LRU算法的实现2 (链表+哈希)
此题让我们实现一个LRU的模板类。本题较简便且高效的写法是维护一个std::list和一个std::unordered_map。
std::list 与 std::unordered_map 中存放的内容
std::list中存放各key,类型为K。链表中各键码存放的顺序是按照访问顺序存放的。
std::unordered_map中以key为第一维,第二维为一个pair,其first和second分别为:
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)\)。
参考代码实现
#include <list>
#include <unordered_map>
template <typename K, typename V>
class LRU {
private:
typedef typename std::list<K>::iterator listIter;
typedef typename std::unordered_map<K, std::pair<V, listIter>>::iterator unorderedMapIter;
std::list<K> lst;
std::unordered_map<K, std::pair<V, listIter>> mp;
public:
void insert(const K &key, const V &value) {
unorderedMapIter it = mp.find(key);
if (it == mp.end()) {
lst.emplace_back(key);
mp.insert(std::make_pair(key, std::make_pair(value, --lst.end())));
} else {
lst.erase(it->second.second);
lst.emplace_back(key);
it->second = std::make_pair(value, --lst.end());
}
}
// If Key doesn't exist, this will create one <Key, zero>
V get(const K &key) {
return mp[key].first;
}
bool contains(const K &key) {
return mp.count(key) == 1;
}
void vis(const K &key) {
unorderedMapIter it = mp.find(key);
if (it != mp.end()) {
lst.erase(it->second.second);
lst.emplace_back(key);
it->second.second = --lst.end();
}
}
void pop() {
if (!lst.empty()) {
mp.erase(lst.front());
lst.pop_front();
}
}
void remove(const K &key) {
unorderedMapIter it = mp.find(key);
if (it != mp.end()) {
lst.erase(it->second.second);
mp.erase(it);
}
}
bool emtpy() { // 注意本题要求函数名为emtpy
return lst.empty();
}
unsigned long long size() {
return lst.size();
}
void clear() {
lst.clear();
mp.clear();
}
};
FJUTOJ-3682 LRU算法的实现2 (链表+哈希)的更多相关文章
- java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现
java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析 ...
- [整理] LRU 算法的实现方式
目录 概念 方法选择 实现方案(基于LinkedHashMap) 改进方案 1.LRU-K 2.Two queue 3.Multi Queue(MQ) LRU类算法对比 LRU 在 Redis 中的应 ...
- linkedhashmap中关于LRU算法的实现
//LinkedHashMap的一个构造函数,当参数accessOrder为true时,即会按照访问顺序排序,最近访问的放在最前,最早访问的放在后面 public LinkedHashMap(int ...
- Python学习(三) 八大排序算法的实现(下)
本文Python实现了插入排序.基数排序.希尔排序.冒泡排序.高速排序.直接选择排序.堆排序.归并排序的后面四种. 上篇:Python学习(三) 八大排序算法的实现(上) 1.高速排序 描写叙述 通过 ...
- Bug2算法的实现(RobotBASIC环境中仿真)
移动机器人智能的一个重要标志就是自主导航,而实现机器人自主导航有个基本要求--避障.之前简单介绍过Bug避障算法,但仅仅了解大致理论而不亲自动手实现一遍很难有深刻的印象,只能说似懂非懂.我不是天才,不 ...
- Canny边缘检测算法的实现
图像边缘信息主要集中在高频段,通常说图像锐化或检测边缘,实质就是高频滤波.我们知道微分运算是求信号的变化率,具有加强高频分量的作用.在空域运算中来说,对图像的锐化就是计算微分.由于数字图像的离散信号, ...
- SSE图像算法优化系列十三:超高速BoxBlur算法的实现和优化(Opencv的速度的五倍)
在SSE图像算法优化系列五:超高速指数模糊算法的实现和优化(10000*10000在100ms左右实现) 一文中,我曾经说过优化后的ExpBlur比BoxBlur还要快,那个时候我比较的BoxBlur ...
- 详解Linux内核红黑树算法的实现
转自:https://blog.csdn.net/npy_lp/article/details/7420689 内核源码:linux-2.6.38.8.tar.bz2 关于二叉查找树的概念请参考博文& ...
- 详细MATLAB 中BP神经网络算法的实现
MATLAB 中BP神经网络算法的实现 BP神经网络算法提供了一种普遍并且实用的方法从样例中学习值为实数.离散值或者向量的函数,这里就简单介绍一下如何用MATLAB编程实现该算法. 具体步骤 这里 ...
随机推荐
- nuget打包上传
准备工作 下载nuget.exe,以及gui推送编辑工具 Nuget Package Explorer (可选) 设置nuget环境变量. 流程 完成项目 cmd控制台cd到项目目录下(项目目录不是解 ...
- C#设计模式学习笔记:(6)适配器模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7640873.html,记录一下学习过程以备后续查用. 一.引言 从今天开始我们开始讲结构型设计模式,结构型设 ...
- vsto 学习
Object到String类型转换的四种方式 通常object到string有四种方式:(假设有object obj) obj.ToString, Convert.ToString, (string) ...
- CentOS配置禁止root用户直接登录
Linux的默认管理员名即是root,只需要知道ROOT密码即可直接登录SSH.禁止Root从SSH直接登录可以提高服务器安全性.经过以下操作后即可实现.本文适用于CentOS.Debian等Linu ...
- MAC安装MacPorts 卡在“正在运行软件包脚本”的解决办法
MAC安装MacPorts 卡在"正在运行软件包脚本"的解决办法 点击右上角强制结束掉"安装器" 打开terminal, 输入命令"ps -ef | ...
- selenium实现网易邮箱的登录注册
#实现163网站的注册 from selenium import webdriver import time driver = webdriver.Chrome() url = 'https://ma ...
- 安装MYSQL到Ubuntu(APT)
运行环境 系统版本:Ubuntu 16.04.6 LTS 软件版本:MYSQL-5.7 硬件要求:无 安装过程 1.安装APT-MYSQL存储库 APT-MYSQL存储库由MYSQL官网提供.选择安装 ...
- 吴裕雄--天生自然 python数据分析:医疗费数据分析
import numpy as np import pandas as pd import os import matplotlib.pyplot as pl import seaborn as sn ...
- echarts 【图表的基本使用】
一.柱状图 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <tit ...
- ES6数组去重方法
Set实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员),操作方法有:add(value).delete(value).has(value).clear():遍历方法有:keys ...