Implementación de caché LRU

1. Descripción del título

2. Implementación del código


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;
}

 

Supongo que te gusta

Origin blog.csdn.net/MOU_IT/article/details/113816486
Recomendado
Clasificación