最近最少使用(LRU, Least recently used)缓存算法_华为2023

news2024/11/25 2:29:27

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路

性能限制很高、数据量很大时,cin、cout肯定是不够快的。
(1)可以利用getchar()速度快的特性设计快读函数读取整数,可以做到用scanf()函数5倍的速度读入任意整数:

#include<cstdio>
// 仅正整数可用
#define read(a) {char c;while((c=getchar())>47) a=a*10+(c^48);}
// 正负整数均可用
inline void read(int& a)
{
	int s = 0, w = 1;
	char ch = getchar();
	while (ch < '0' || ch>'9')
	{//为了避免输入数字之前的空格造成影响以及判断正负
		if (ch == '-') { w = -1; }
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9')
	{
		s = s * 10 + ch - '0';
		ch = getchar();
	}
	a = s * w;
}

(2)快写,注意中printf()也比cout快,如果输出不是int类型,可以用printf(“<式样化字符串>”,<参数表>);

printf( "%s", s );                                                 // 输出string
printf(%.3s“, hello);或者 printf("message: '%.*s'\n", 3, hello);  // 输出指定宽度的string
bool b=true; if(b) printf("true"); else printf("false");          // 输出bool类型变量
printf("%d",int_num)                                              // 输出整数型变量
#include<cstdio>
inline void write(int n)
{
	if (n < 0)
	{
		putchar('-');
		n *= -1;
	}
	if (n > 9)
	{
		write(n / 10);
	}
	putchar(n % 10 + '0');
}

(3)快速存取:使用满足 LRU (最近最少使用) 缓存 约束的数据结构

思路:使用一个双指针链表和一个哈希表,所有增删查改复杂度为O(1)
  1.双链表表示资源池,存储处于空闲状态的结点;结点包含左右指针,key:value,key表示id编号,value表示此时结点是否处于被占用状态。0表示被占用,1表示空闲。
  2.哈希表unordered_map<int,Node*>存储id=key对应的链表中的节点, 用于快速查找链表中结点的位置以便增删改查。
  3.初始化:双链表资源池和哈希表key根据资源池范围初始化,value全部设定为空闲状态1;
  4.操作:分配的本质是从资源池中删除,释放的本质是添加到资源池的末尾
    1>动态分配k个资源:
      用双链表遍历前k个node,如果node对应的value为1,则依次置0,并从双链表中删除node
    2>指定分配第k个资源
      用哈希表查找key=k的node;
      如果node对应的value为1,则置0,双链表将该node删除;
    3>释放第k个资源:
      用哈希表判断key对应的结点;
      判断是否被占用(value是否为0)。如果为0,则value置为1表示空闲,同时将key对应的节点放到双链表的最右侧;
  5.输出:资源池的第一个空闲资源id即链表的第一个结点的key。注意这题保证每个用例最后都有空闲资源ID。

代码如下:

# include<unordered_map>
# include<cstdio>
# include<iostream>
using namespace std;

struct Node {
    int key;
    int value;
    Node* left, * right;
    Node(int _key, int _value) : key(_key), value(_value), left(NULL), right(NULL) {}
};//双链表的最左和最右节点,不存贮值。

class LRUCache {
public:
    Node* L;
    Node* R;
    LRUCache() {
            L = new Node(-1,-1),R = new Node(-1,-1);
            L->right = R;
            R->left = L;    
        }

    void remove(Node* p)
    {
        p->right->left = p->left;
        p->left->right = p->right;
        p->value=0;
        //cout<<"id:"<<p->key<<" remove"<<endl;
    }

    void insert(Node *p)
    {
        p->right = R;
        p->left = R->left;
        R->left->right = p;
        R->left = p;
        p->value=1;
        //cout<<"id:"<<p->key<<" insert"<<endl;
    }
    
};

inline void read(int& a)
{
	int s = 0;
	char ch = getchar();
	while (ch < '0' || ch>'9') ch = getchar();
	while (ch >= '0' && ch <= '9')
	{
		s = s * 10 + ch - '0';
		ch = getchar();
	}
	a = s;
}

int main() {
    int start, end;
    read(start);read(end);
    //cout<<"s "<<start<<" e "<<end<<endl;
    LRUCache* pool = new LRUCache();  //双链表
    unordered_map<int,Node*>hash;  // 哈希表
    for (int id =start;id<=end;id++){
        Node* resource = new Node(id,1);
        pool->insert(resource);  // 初始化双链表
        hash[id] = resource;     // 初始化哈希表
    }
    int opnums;read(opnums);
    int opk,opn;
    for (int op =0;op<opnums;op++){
        read(opk);  //操作的类型
        read(opn);  //操作的参数
        if (opk==1){
            if (opk>end-start+1) opn=end-start+1;
            for (int index = 0;index<opn;index++){
                Node *p=pool->L->right;
                if (p->value>0) pool->remove(p);
            }
        }
        if (opk==2){
            //cout<<"操作2指定分配"<<endl;
            if (hash.count(opn)) {
                Node *p=hash[opn];
                if (p->value>0) pool->remove(p);}
        }
        if (opk==3){
            //cout<<"操作2释放"<<endl;
            if(hash.count(opn)) {
                Node *p=hash[opn];
                if (!p->value) pool->insert(p);}
        }
    }
    printf("%d", pool->L->right->key);
    return 0;
}

参考博文:https://blog.csdn.net/a_beatiful_knife/article/details/130413929

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

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

相关文章

u盘恢复数据方法有哪些(u盘恢复数据方法)

嘿小伙伴们&#xff0c;今天咱们来聊聊一个小问题&#xff0c;就是当我们的U盘不小心丢失了重要数据&#xff0c;怎么办呢&#xff1f;没关系&#xff0c;这里我就为大家介绍几种U盘恢复数据的方法。 u盘恢复数据方法有哪些 1,首先&#xff0c;最简单粗暴的方法就是使用Windo…

Redis分片集群

目录 搭建分片集群 散列插槽 集群伸缩 故障转移 数据迁移 RedisTemplate访问分片集群 搭建分片集群 主从&#xff08;一个主节点、多个子节点&#xff0c;读写分离&#xff09;和哨兵&#xff08;解决主节点宕机问题&#xff09;可以解决高可用、高并发读的问题。但是依然…

如何更改pdf文件的默认打开程序?

在Windows系统中&#xff0c;有时安装一些软件或执行一些操作&#xff0c;会自动将打开某种类型文件的默认程序给修改掉&#xff0c;这样后续打开文件时可能会很别扭&#xff0c;于是我们想把打开文件的默认工具设置指定的软件。 以打开pdf文件为例&#xff0c;某天打开pdf文件…

基于Zynq的雷达10Gbps高速PCIE数据采集卡方案(三)软件设计

4.1 引言 本章基于第二章的分析结论&#xff0c;进行系统软件设计。软件设计包括逻辑设计、嵌入 式软件设计和上位机软件设计。在逻辑设计中&#xff0c;对 ADC 模块、 Aurora 模块、 DDR3 SDRAM 模块和 PCIE 模块进行分析和设计&#xff0c;在 Vivado 软件提供的 …

BI技巧丨计算组柱形图

PowerBI中&#xff0c;我们经常使用柱形图来进行趋势对比分析&#xff0c;通过柱形图我们可以直观展示每个月之间的差异。 但是在实际需求中&#xff0c;PowerBI原生的柱形图仅能展示一个数据标签&#xff0c;如果我们想要展示同环比的变化情况&#xff0c;往往需要将同环比的…

Metal入门学习:GPU并行计算大数组相加

一、编程指南PDF下载链接(中英文档&#xff09; 1、Metal编程指南PDF链接 https://github.com/dennie-lee/ios_tech_record/raw/main/Metal学习PDF/Metal 编程指南.pdf 2、Metal着色语言(Metal Shader Language:简称MSL)编程指南PDF链接 https://github.com/dennie-lee/ios_te…

【王道·计算机网络】第六章 应用层

一、基本概念 1.1 应用层概述 应用层对应用程序的通信提供服务应用层协议定义&#xff1a; 应用进程交换的报文类型&#xff0c;请求还是响应?各种报文类型的语法&#xff0c;如报文中的各个字段及其详细描述字段的语义&#xff0c;即包含在字段中的信息的含义进程何时、如何…

PathWise开发(1) 将增加节点的功能移动到鼠标右键 d3.js/vue.js

PathWise(1) 从零开始搭建知识图谱/个性化学习路径/d3.js/vue.js 2023年5月20日&#xff1a;将增加节点的功能移动到鼠标右键 跑起来先 思路&#xff1a; 将我们之前的MyTableAddNode.vue&#xff0c;删除其中的内容只留下下面的表单<template><!-- <div class…

【Linux Network】高级IO

目录 前言 五种IO模型 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO 小结 同步通信 vs 异步通信 阻塞 vs 非阻塞 其他高级IO 非阻塞IO fcntl函数 代码测试 高级IO&#x1f337; 前言 IO&#xff1a;所谓的I便是 input&#xff0c;所谓的O便是 output&#xff0c;简单点来说&a…

VC++6.0掌握哈希表的基本操作和掌握几种内部排序的方法

问题描述 针对某个集体中人名设计一个哈希表&#xff0c;使得平均查找长度不超过R&#xff0c;并完成相应的建表和查表程序。 1.2基本要求 假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个&#xff0c;取平均查找长度的上限为2。哈希函数用除留余数法构造&…

【掌控安全】sql注入全集

掌控安全 &#x1f525;系列专栏&#xff1a;掌控安全 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2023年5月20日&#x1f334; &#x1f36d;作者水平很有限&#xff0c;如果发现错误&…

Linux---文件操作命令(touch、cat、more)

1. touch命令 可以通过touch命令创建文件 语法&#xff1a;touch [选项] Linux路径 touch命令&#xff0c;参数必填&#xff0c;表示要创建的文件路径&#xff0c;相对、绝对、特殊路径符均可以使用。 touch 命令不光可以用来创建文件&#xff08;当指定操作文件不存在时&a…

【Redis】聊一下缓存雪崩、击穿、穿透、预热

缓存的引入带来了数据读取性能的提升&#xff0c;但是因此也引入新的问题&#xff0c;一个是数据双写一致性&#xff0c;另一个就是雪崩、击穿、穿透&#xff0c;那么如何解决这些问题&#xff0c;我们来说下对应的问题和解决方案 雪崩 缓存雪崩&#xff1a;同一时间内大量请…

pg事务:事务相关元组结构

事务相关的元组结构 元组结构中包含很多pg的mvcc所必要的信息&#xff0c;下面的内容将梳理xmin,xmax,t_ctid,cmin,cmax,combo cid,tuple id的含义和关系 物理结构 HeapTupleHeaderData相当于tuple的header&#xff0c;其结构在src/include/access/htup_details.h中定义 typ…

【BIO、NIO、AIO、Netty】

什么是IO Java中I/O是以流为基础进行数据的输入输出的&#xff0c;所有数据被串行化(所谓串行化就是数据要按顺序进行输入输出)写入输出流。简单来说就是java通过io流方式和外部设备进行交互。在Java类库中&#xff0c;IO部分的内容是很庞大的&#xff0c;因为它涉及的领域很广…

win--C盘程序员常见应用内存空间处理

写在前面&#xff1a; 本篇用于记录我对于C盘各个应用内存处理的总结&#xff0c; 文章目录 前置知识vscode的.vscode文件迁移可以移动 软件推荐wsl和docker存储管理修改安装目录压缩磁盘 pip缓存清理JetBrains系列 前置知识 在win中有着这样一个命令mklink&#xff0c;可以…

Java飞行记录器

目录 JFR和JMC启动飞行记录用JFR对比不同GC器运行结果记录结果GC配置GC Summary垃圾收集 JFR和JMC JFR全称为Java Flight Recorder&#xff0c;即Java飞行记录器 JMC全称为JDK Mission Control&#xff0c;即JDK任务控制 先贴一段官网的简介&#xff1a; Java Flight Recorder…

基于鸿蒙系统的智能衣柜管理系统设计与实现_kaic

摘 要 随着城市的扩大与科学技术的发展&#xff0c;人们逐渐开始关注衣柜功能的改进&#xff0c;存储效果的优化和智能使用的升级。个性化、功能化、智能化的衣柜将出现在人们的家庭生活中&#xff0c;并且起到重要作用。 为了满足当前人们对智能衣柜的需求&#xff0c;本设计…

面试真的被问麻了......

前几天组了一个软件测试面试的群&#xff0c;没想到效果直接拉满&#xff0c;看来大家对面试这块的需求还是挺迫切的。昨天我就看到群友们发的一些面经&#xff0c;感觉非常有参考价值&#xff0c;于是我就问他还有没有。 结果他给我整理了一份非常硬核的面筋&#xff0c;打开…

Java -并发(多线程)-Interview面试题收集

1、多线程并发 1&#xff09;多线程中 synchronized 锁升级的原理是什么&#xff1f; synchronized 锁升级原理&#xff1a;在锁对象的对象头里面有一个 threadid 字段&#xff0c;在第一次访问的时候 threadid 为空&#xff0c;jvm 让其持有偏向锁&#xff0c;并将 threadid…