LRU缓冲机制

LRU缓冲机制

在这里插入图片描述

使用有序字典

class LRUCache(collections.OrderedDict): # collections.OrderedDict

    def __init__(self, capacity: int):
        super().__init__() # 初始化父类(超类)
        self.capacity = capacity



    def get(self, key: int) -> int:
        if key not in self:
            return -1
        self.move_to_end(key)
        return self[key]



    def put(self, key: int, value: int) -> None:
        if key in self:
            self.move_to_end(key)
        self[key] = value
        if len(self) > self.capacity:
            self.popitem(last = False)



# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)

使用字典加双向链表

class DLinkedNode:
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.prev = None
        self.next = None

class LRUCache:

    def __init__(self, capacity: int):
        self.phead = DLinkedNode(0, 0)
        self.ptail = DLinkedNode(0, 0)
        self.phead.next = self.ptail
        self.ptail.prev = self.phead

        self.capacity = capacity
        self.cache = {}
        self.size = 0

    

    def get(self, key: int) -> int:
        if key not in self.cache.keys():
            return -1
        node = self.cache[key]
        self.moveToHead(node)
        return node.value


    def put(self, key: int, value: int) -> None:
        if key in self.cache.keys():
            node = self.cache[key]
            node.value = value
            self.moveToHead(node)
        else:
            self.size += 1
            newNode = DLinkedNode(key, value)
            self.cache[key] = newNode
            self.addToHead(newNode)
        if self.size > self.capacity:
            removed = self.removeTail()
            self.cache.pop(removed.key)
            self.size -= 1
        



    def removeNode(self, node):
        node.prev.next = node.next
        node.next.prev = node.prev

    def addToHead(self, node):
        tmp = self.phead.next
        self.phead.next = node
        node.prev = self.phead
        node.next = tmp
        tmp.prev = node

        """
        node.prev = self.phead
        node.next = self.phead.next
        self.phead.next.prev = node
        self.phead.next = node
        """
    def moveToHead(self, node):
        self.removeNode(node)
        self.addToHead(node)
    
    def removeTail(self):
        node = self.ptail.prev
        self.removeNode(node)
        return node


# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)

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

牛客网题目 LRU缓存机制

在这里插入图片描述

使用有序字典:

#
# lru design
# @param operators int整型二维数组 the ops
# @param k int整型 the k
# @return int整型一维数组
#
#
# lru design
# @param operators int整型二维数组 the ops
# @param k int整型 the k
# @return int整型一维数组
#
import collections
class Solution:
    def __init__(self, k):
        self.dic = collections.OrderedDict()
        self.capacity = k # k表示剩余容量

    def get(self, key):
        if key not in self.dic: return -1
        val = self.dic.pop(key) # 返回键值, 但是也没必要这一项弹出来啊,可以改该
        print("val", val)
        self.dic[key] = val
        return val

    def set(self, key, value): # 这里是弹出来,然后又加进入,相当于把这一项移动到末尾。
        if key in self.dic:
            self.dic.pop(key)
        else:
            if self.capacity > 0:
                self.capacity -= 1
            else:
                self.dic.popitem(last=False) # 把最前面的弹出来,最末尾的表示最近访问过的。
        self.dic[key] = value

s = input().strip()
print("s", s)
idx = s.index("]],")
k = int(s[idx+3:])
ss = s[:idx]
aa = ss.strip("[[").split("],[")
s = Solution(k)
res = []
for r in aa:
    ss = list(map(int, r.strip().split(",")))
    if ss[0] == 1:
        s.set(ss[1], ss[2])
    elif ss[0] == 2:
        x = s.get(ss[1])
        res.append(x)
print(str(res).replace(" ", ""))

普通字典 + 链表

#
# lru design
# @param operators int整型二维数组 the ops
# @param k int整型 the k
# @return int整型一维数组
#
class node:
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.pre = None
        self.next = None


class Solution:
    def LRU(self, operators, k):
        # write code here
        self.cache = {}
        self.nums = 0
        self.result = []
        self.pHead = node(0, 0)
        self.pTail = node(0, 0)
        self.pHead.next = self.pTail
        self.pTail.pre = self.pHead
        for item in operators:
            ops, *res = item
            # print("ops, res", ops, res)
            if ops == 1:
                key, value = res
                # print("key, value", key, value)
                if key not in self.cache.keys():
                    self.cache[key] = node(key, value)
                    # print("not in keys()", key)
                    self.addToHead(key)
                    self.nums += 1
                else:
                    self.cache[key].value = value
                    # print("self.cache",self.cache)
                    # print("key1", key)
                    self.moveToHead(key)
                if self.nums > k:
                    delkey = self.pTail.pre.key
                    # print("delkey", delkey)
                    self.removeNode(delkey)
                    self.cache.pop(delkey)  # 根据最后一个节点来定位
                    self.nums -= 1
            else:
                key = res[0]
                # print("else key", key)
                if key in self.cache.keys():
                    self.result.append(self.cache[key].value)
                    self.moveToHead(key)
                else:
                    self.result.append(-1)
        return self.result

    def addToHead(self, key):
        node1 = self.cache[key]
        node1.pre = self.pHead
        node1.next = self.pHead.next
        self.pHead.next = node1
        node1.next.pre = node1

    def removeNode(self, key):
        node2 = self.cache[key]
        node2.pre.next = node2.next
        node2.next.pre = node2.pre

    def moveToHead(self, key):
        self.removeNode(key)
        self.addToHead(key)

普通字典 + 链表 更清晰的方式

注意删除链表节点和删除字典的节点, 这个时候的处理,先将待删除节点单独拿出来,再处理。

#
# lru design
# @param operators int整型二维数组 the ops
# @param k int整型 the k
# @return int整型一维数组
#
class node:
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.pre = None
        self.next = None


class Solution:
    def LRU(self, operators, k):
        # write code here
        self.cache = {}
        self.capacity = 0
        self.k = k
        self.res = []
        self.pHead = node(0, 0)
        self.pTail = node(0, 0)
        self.pHead.next = self.pTail
        self.pTail.pre = self.pHead
        for item in operators:
            flag, *reslist = item  # reslist 是一个列表
            if flag == 1:
                key, value = reslist
                self.set(key, value)
            else:
                key = reslist[0]
                a = self.get(key)
                self.res.append(a)
        return self.res

    def set(self, key, value):
        if key in self.cache.keys():
            node1 = self.cache[key]
            node1.value = value
            self.moveToHead(node1)
        else:
            newnode = node(key, value)
            self.cache[key] = newnode # 将节点加入缓存
            self.addToHead(newnode)
            self.capacity += 1
            if self.capacity > self.k:
                removednode = self.pTail.pre  # 待删除的节点
                self.removeNode(removednode)  # 从链表中断开
                self.cache.pop(removednode.key)  # 从缓存中弹出
                self.capacity -= 1

    def get(self, key):
        if key not in self.cache.keys():
            return -1
        node2 = self.cache[key]
        self.moveToHead(node2)
        return node2.value

    def removeNode(self, node):
        node.pre.next = node.next
        node.next.pre = node.pre

    def addToHead(self, node):
        node.pre = self.pHead
        node.next = self.pHead.next
        self.pHead.next = node
        node.next.pre = node

    def moveToHead(self, node):
        self.removeNode(node)
        self.addToHead(node)


# str = input()
# liststr = str[:-2]
# # string = "list1 = " + liststr
# string2 = "list1 = list(" + liststr + ")"
# exec(string2)
# nums = int(str[-1])
# print(list1, nums)
# print(len(list1))

list1 = [[1,1,1],[1,2,2],[1,3,2],[2,1],[1,4,4],[2,2]]
sol = Solution()
k = 3
res1 = sol.LRU(list1,k)
print("res1",res1)

更新(2020-10-5):普通字典+链表

#
# lru design
# @param operators int整型二维数组 the ops
# @param k int整型 the k
# @return int整型一维数组
#
class Node:
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.next = None
        self.pre = None


class Solution:
    def __init__(self):
        self.cache = {}
        self.capacity = 0
        self.head = Node(0, 0)
        self.tail = Node(0, 0)
        self.head.next = self.tail
        self.tail.pre = self.head
        self.result = []

    def LRU(self, operators, k):
        # write code here
        self.capacity = k
        for item in operators:
            flag, *res_list = item
            if flag == 1:
                key, value = res_list
                self.set(key, value)

            else:
                key = res_list[0]
                value_return = self.get(key)  # 返回节点的值
                self.result.append(value_return)
        return self.result

    def set(self, key, value):
        if key in self.cache.keys():
            cur_node = self.cache[key]
            cur_node[key] = value
            self.move_to_head(cur_node)
        else:
            new_node = Node(key, value)
            self.add_to_head(new_node)
            self.cache[key] = new_node  # 之前忘了加进去
            self.capacity -= 1
            if self.capacity < 0:  # 不能写成 <= 0 , 当 == 0 时,表明还没有溢出, 只有绝对小于0时才能进行删除操作
                node_to_delet = self.tail.pre
                self.remove_node(node_to_delet)
                self.capacity += 1
                self.cache.pop(node_to_delet.key)

    def get(self, key):  # 返回节点的值 或者 -1
        if key not in self.cache.keys():
            return -1
        cur_node = self.cache[key]
        self.move_to_head(cur_node)
        return cur_node.value

    def remove_node(self, node):
        node.pre.next = node.next
        node.next.pre = node.pre

    def add_to_head(self, node):
        node.pre = self.head
        node.next = self.head.next
        self.head.next = node
        node.next.pre = node

    def move_to_head(self, node):
        self.remove_node(node)
        self.add_to_head(node)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值