Amazon OA2准备——LRU cache

这道题目可以在leetcode找到

https://leetcode.com/problems/lru-cache/

============================================================================

Amazon OA中的题面是:

给一个array, 给一个cache max size, 输出miss count. 什么时候hit, 什么时候miss的情况写好就好了。

example:   size = 4, input array   【1,2,3,4,5,4,1】

1 miss   2 miss   3 miss   4 miss   5 miss  替换 1   

4 hit    把4提前到第一位   1 miss  替换 2

============================================================================


一亩三分地中大家说的这个题目我没太看明白。。。使用了4,4放到第一个,然后使用了1,1不是应该在第一个吗?干嘛要替换2?

到前4个应该是[4,3,2,1]-》[5,4,3,2]-》[4,5,3,2]-》[1,4,5,3]我是这么理解的


============================================================================

所以我们翻回去看看操作系统好了


这里只关注LRU

LRU:最近最少使用(Least Recently Used).替换上次使用距离当前最远的页。根据局部性原理:替换最近最不可能 访问到的页。核心思想是,如果最近被访问,那么以后被访问的几率大。

性能最接近OPT,但难以实现。可以维护一个关于访问页的栈或者给每个页添加最后访问的时间标签,但开销都很大。

 分析:(F表示页帧最初填满时出现page fault)

 a.需要页面2,内存中还有空闲位置,直接加入页面2

 b.需要页面3,内存中还有空闲位置,直接加入页面3

 c.需要页面2,内存中已经存在页面2,不加入任何页面,这里重置了2的最近历史访问记录

 d.需要页面1,内存中还有空闲位置,直接加入页面1

 e.需要页面5,页面2,3,1距离最近一次历史访问的距离依次为2,3,1(步骤c中重置了2的访问记录).所以替换掉页        面3.

 f.需要页面2,内存中已经存在页面2,不加入任何页面,重置页面2的访问记录

 g.需要页面4,页面2,5,1距离最近一次历史访问的距离依次是1,2,3,所以替换掉页面1

 h.需要页面5,内存中存在页面5,不改变,重置页面5的访问记录

 i.需要页面3,页面2,5,4距离最近一次历史访问的距离依次为3,1,2,所以替换掉页面2

 j.需要页面2,页面3,5,4距离最近一次历史访问的距离依次为1,2,3,所以替换掉页面4

 k.需要页面5,内存中存在页面5,不改变

 L.需要页面2,内存中存在页面2,不改变


重新看一遍,按照上图的写法再写一遍
[1,2,3,4],[5,2,3,4],[4,5,2,3],[4,5,1,3]
看看原来的
[4,3,2,1],[5,4,3,2],[4,5,3,2],[1,4,5,3]
其实我这样的写法也没有错,因为我在排序的时候给它换成了最少使用在队头(或者队尾,看使用的数据结构)。


我选择了使用HashMap和List。

这里给出的算法是Leetcode中刷题的。之后在Eclipse中再写一个补上。

public class LRUCache {
    HashMap<Integer, Integer> map;
    ArrayList<Integer> list;
    int max;
    public LRUCache(int capacity) {
        map = new HashMap<Integer, Integer>(capacity);
        list = new ArrayList<Integer>(capacity);
        max = capacity;
    }
    
    public int get(int key) {
        if(map.containsKey(key))
        {
            list.remove(new Integer(key));
            list.add(key);
            return map.get(key);
        }
        else
        return -1;
    }
    
    public void set(int key, int value) {
        if(map.containsKey(key))
        {
            map.put(key, value);  
            list.remove(new Integer(key));   
            list.add(key);
        }
        else
        {
            if(map.size() < max)
            {
                map.put(key,value);
                list.add(key);
            }else
            {
                int leastkey = list.remove(0);  
                list.add(key);  
                map.remove(leastkey);  
                map.put(key, value); 
            }
        }
        
    }
}


给出完整的实现,还是用的之前的hashmap和list实现的方法

package quinn;

import java.util.ArrayList;
import java.util.HashMap;

public class LRUcache {
	
	static HashMap<Integer, Integer> map;
	static ArrayList<Integer> list;
	int capacity;
		
	
	public LRUcache(int capacity_val)
	{
		capacity = capacity_val;
		map = new HashMap<Integer,Integer>(capacity);
		list = new ArrayList<Integer>(capacity);
	}
		
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] array = {4,3,4,2,3,1,4,2};
		int max = 3;
		
		LRUcache MemoA = new LRUcache(max);

		for(int i = 0; i < array.length; i++)
		{
			MemoA.set(array[i], i);
			
			outputlist();
		}
		
		int findx = MemoA.get(4);
		if(findx == -1)
			System.out.println("Do not have now");
		else
		{
			System.out.println("result is: "+findx);
			outputlist();
		}
	}

	private static void outputlist() {
		// TODO Auto-generated method stub
		System.out.print("[ ");
		for(int j=0; j < list.size();j++)
		{
			System.out.print(list.get(j)+" ");
		}
		System.out.print("]\n");
		
	}

	private int set(int key, int i2) {
		// TODO Auto-generated method stub
		if(map.size() < capacity)
		{
			if(map.containsKey(key))
			{
				map.put(key, i2);
				list.remove(new Integer(key));
				list.add(key);
			}else
			{
				map.put(key, i2);
				list.add(key);				
			}
		}
		else
		{
			int lastkey = list.get(0);
			list.remove(0);
			map.remove(lastkey);
			
			list.add(key);
			map.put(key, i2);
			
		}
		return key;
	}

	private int get(int key) {
		// TODO Auto-generated method stub
		
		if(map.containsKey(key))
		{
			list.remove(new Integer(key));
			list.add(key);
			return map.get(key);
		}else
			return -1;
	}

}

给出一个LinkedHashMap的实现,来自于:

http://yikun.github.io/2015/04/03/%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AALRU-Cache%EF%BC%9F/

简便很多。


package quinn;

import java.util.Iterator;
import java.util.Map;

public class LRUCache2 {
    
    private int capacity;
    private static Map<Integer, Integer> cache;
    
    public LRUCache2(final int capacity) {
        this.capacity = capacity;
        this.cache = new java.util.LinkedHashMap<Integer, Integer> (capacity, 0.75f, true) {
            // 定义put后的移除规则,大于容量就删除eldest
            protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
                return size() > capacity;
            }
        };
    }
    
    public int get(int key) {
        if (cache.containsKey(key)) {
            return cache.get(key);
        } else
            return -1;
    }
    
    public void set(int key, int value) {
        cache.put(key, value);
    }

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] array = {4,3,4,2,3,1,4,2};
		int max = 3;
		
		LRUCache2 MemoA = new LRUCache2(max);

		for(int i = 0; i < array.length; i++)
		{
			MemoA.set(array[i], i);
		}
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LRU Cache是一种常见的缓存淘汰策略,LRU代表最近最少使用。在Java中,可以使用不同的方式来实现LRU Cache。 引用\[1\]中的代码展示了一种自定义的LRU Cache实现,使用了一个自定义的LRUCache类,并在main方法中进行了测试。在这个实现中,LRUCache类继承了LinkedHashMap,并重写了removeEldestEntry方法来实现缓存的淘汰策略。 引用\[2\]中的代码展示了另一种自定义的LRU Cache实现,同样使用了一个自定义的LRUCache类,并在main方法中进行了测试。这个实现中,LRUCache类同样继承了LinkedHashMap,并重写了removeEldestEntry方法来实现缓存的淘汰策略。 引用\[3\]中的代码展示了使用ArrayList实现LRU Cache的方式。在这个实现中,LRUCache类使用了一个ArrayList来存储缓存数据,并通过get和put方法来操作缓存。 总结来说,LRU Cache的Java实现可以使用自定义的类继承LinkedHashMap并重写removeEldestEntry方法,或者使用ArrayList来存储缓存数据。具体的实现方式可以根据需求和偏好选择。 #### 引用[.reference_title] - *1* *2* [Java——LRUCache](https://blog.csdn.net/m0_60867520/article/details/128361042)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [LRUCache的Java实现](https://blog.csdn.net/qq_39383118/article/details/103535985)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值