LRU缓存的实现

1、题目描述

2、代码实现


1、题目描述

    设计LRU缓存结构,该结构在构造时确定大小,假设大小为K,并有如下两个功能

  • set(key, value):将记录(key, value)插入该结构
  • get(key):返回key对应的value值

    要求:

  • 1、set和get方法的时间复杂度为O(1)
  • 2、某个key的set或get操作一旦发生,认为这个key的记录成了最常使用的。
  • 3、当缓存的大小超过K时,移除最不经常使用的记录,即set或get最久远的。

2、代码实现

    使用STL中的map和list可以实现一个LRU缓存,定义结构体为:

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

  具体实现如下:

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

猜你喜欢

转载自blog.csdn.net/MOU_IT/article/details/113816486