1. Descripción del título
Diseñe la estructura de la caché LRU, la estructura se determina en el momento de la construcción, asumiendo que el tamaño es K, y tiene las siguientes dos funciones
- conjunto (clave, valor): inserta el registro (clave, valor) en la estructura
- get (clave): Devuelve el valor correspondiente a la clave
Afirmar:
- 1. La complejidad temporal de los métodos set y get es O (1)
- 2. Una vez que se produce una operación de configuración o obtención de una clave, se considera que el registro de esta clave es el más utilizado.
- 3. Cuando el tamaño de la caché exceda K, elimine el registro utilizado con menos frecuencia, es decir, el conjunto más antiguo u obtener.
2. Implementación del código
Se puede implementar una caché LRU usando mapa y lista en STL, y la estructura se define como:
struct LruCache
{
/* LRU的容量大小 */
unsigned int capacity = 3;
/* content中保存(key,<key-pointer, value>)的键值对 */
map<string, pair<list<string>::iterator, string> > content;
/* list中保存键值key */
list<string> keyList;
};
La implementación específica es la siguiente:
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <map>
#include <vector>
#include <list>
#include <bitset>
#include <stack>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#include <limits>
using namespace std;
LruCache lruCache;
/* 设置某个键值对的值 */
void Set(string key, string value)
{
/* 如果map中有这个元素,则更新字典和链表 */
if (lruCache.content.find(key) != lruCache.content.end())
{
list<string>::iterator temp = lruCache.content[key].first;
if (temp == lruCache.keyList.begin()) // 如果是头节点,直接更新
{
lruCache.content[key].second = value;
return;
}
lruCache.keyList.erase(temp);
lruCache.keyList.push_front(key); // 插入更新的元素
lruCache.content[key].first = lruCache.keyList.begin(); // 更新字典
}
else // map中没有这个元素则需要插入
{
lruCache.keyList.push_front(key); // 更新链表
lruCache.content[key] = std::make_pair(lruCache.keyList.begin(), value); // 更新字典
if (lruCache.content.size() > lruCache.capacity) // 超出容量大小需要删除最后一个key
{
string lastKey = lruCache.keyList.back();
lruCache.keyList.pop_back(); // 删除最后一个元素
lruCache.content.erase(lastKey); // 删除map中的pair
}
}
}
/* 获取某个键对应的值 */
string Get(string key)
{
/* 如果map中没有这个元素,直接返回空 */
if (lruCache.content.find(key) == lruCache.content.end())
{
return "-1";
}
else
{
list<string>::iterator temp = lruCache.content[key].first;
/* 如果是头节点,直接返回 */
if (temp == lruCache.keyList.begin())
{
return lruCache.content[key].second;
}
/* 不是头节点则要进行更新 */
lruCache.keyList.erase(temp); // 更新键值链表
lruCache.keyList.push_front(key);
lruCache.content[key].first = lruCache.keyList.begin(); // 更新字典map
return lruCache.content[key].second;
}
}
int main()
{
Set("1", "1");
Set("2", "2");
Set("3", "2");
std::cout << Get("1") << std::endl;
Set("4", "4");
std::cout << Get("2") << std::endl;
}