问题描述:

LRU算法:优先把那些最长时间没使用的对象置换掉。根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

JAVA实现:

测试:

public class preface {

    public static void main(String[] args) {
LRUCache cache = new LRUCache();
cache.set(1, "one");
cache.set(2, "two");
cache.set(3, "three");
cache.set(5, "five");
cache.set(4, "five");
cache.get(2);
cache.set(6, "six");
cache.printCache();// 2,3,4,5,6
}
}

仓促之下写了个脑残版的,到头来也没能正确运行:

public class LRUCache {

    private Map<Integer, pair> cache;
private int _cur; //计数
private int _capacity;
private int _nums = 0;
private heap _h; public class pair implements Comparable { public String value;
public int num; public pair(int num, String value) {
this.num = num;
this.value = value;
} @Override
public int compareTo(Object o) {
return num - ((pair) o).num;
}
} //通过堆来对pairs进行排序
public class heap {
public pair[] pairs; private int _cur; public heap() {
pairs = new pair[5];
for (int i = 0; i < 5; ++i) {
pairs[i] = new pair(0, null);
}
_cur = 0;
} //每次只能修改最上面的pair
public pair set(pair p) {
pair t = pairs[0];
pairs[0] = p;
return t;
} public void insert(pair p) {
if (_cur < 5) {
pairs[_cur] = p;
}
++_cur;
} public void sort() {
Arrays.sort(pairs);
} public int find(pair p) {
for (int i = 0; i < 5; ++i) {
if (pairs[i] == p) { //==比较的是地址,equal比较的是值
return i;
}
}
return -1;
}
} public LRUCache() {
_cur = 0;
_capacity = 0;
cache = new HashMap<Integer, pair>();
_h = new heap();
} public String get(int key) {
++_cur;
if (cache.containsKey(key)) {
return cache.get(key).value;
}
return null;
} public void set(int key, String value) {
++_cur;
if (!cache.containsKey(key)) {
++_nums;
pair p = new pair(_cur, value);
if (_nums == _capacity) {
pair t = _h.set(p);
for (Integer k:cache.keySet()) {
if (cache.get(k) == t) {
cache.remove(t);
break;
}
}
} else {
_h.insert(p);
}
cache.put(key, p);
} else {
pair p = cache.get(key);
int t = _h.find(p);
_h.pairs[t].num = _cur;
_h.pairs[t].value = value;
}
_h.sort();
} public void printCache() {
System.out.println("print cache usage");
for (Integer key:cache.keySet()) {
pair p = cache.get(key);
System.out.println("Key:" + key + " Value:" + p.value + " num:" + p.num);
}
}
}

C++实现:

struct DoubleLinkList {
int key;
int value;
DoubleLinkList *next;
DoubleLinkList *pre;
DoubleLinkList(int k, int v) : key(k), value(v), next(NULL), pre(NULL) {};
}; class LRUCache{
public:
LRUCache(int capacity) {
size = capacity;
cacheMap.clear();
head = new DoubleLinkList(0, 0);
tail = new DoubleLinkList(0, 0);
head->next = tail;
tail->pre = head;
} int get(int key) {
if (cacheMap.find(key) != cacheMap.end()) {
DoubleLinkList *p = cacheMap[key];
spliceNode(p);
addToFront(p);
return p->value;
}
return -1;
} void set(int key, int value) {
if (cacheMap.find(key) == cacheMap.end()) {
DoubleLinkList *p = NULL;
if (cacheMap.size() == size) {
p = tail->pre;
cacheMap.erase(p->key);
p->key = key;
p->value = value;
spliceNode(p);
addToFront(p);
} else {
p = new DoubleLinkList(key, value);
addToFront(p);
}
cacheMap[key] = p;
} else {
DoubleLinkList *p = cacheMap[key];
p->value = value;
spliceNode(p);
addToFront(p);
}
} private:
int size;
map<int, DoubleLinkList*> cacheMap;
DoubleLinkList *head, *tail; void addToFront(DoubleLinkList *p) {
p->pre = head;
p->next = head->next;
head->next->pre = p;
head->next = p;
} void spliceNode(DoubleLinkList *p) {
p->pre->next = p->next;
p->next->pre = p->pre;
}
};

  用list代替双向链表:

struct CacheNode {
int key;
int value;
CacheNode(int k, int v) : key(k), value(v) {
}
}; class LRUCache{
public:
LRUCache(int capacity) {
size = capacity;
} int get(int key) {
if (cacheMap.find(key) != cacheMap.end()) {
auto it = cacheMap[key];
cacheList.splice(cacheList.begin(), cacheList, it);
cacheMap[key] = cacheList.begin();
return cacheList.begin()->value;
} else {
return -1;
}
} void set(int key, int value) {
if (cacheMap.find(key) == cacheMap.end()) {
if (cacheList.size() == size) {
cacheMap.erase(cacheList.back().key);
cacheList.pop_back();
}
cacheList.push_front(CacheNode(key, value));
cacheMap[key] = cacheList.begin();
} else {
auto it = cacheMap[key];
it->value = value;
cacheList.splice(cacheList.begin(), cacheList, it);
cacheMap[key] = cacheList.begin();
}
} private:
int size;
list<CacheNode> cacheList;
unordered_map<int, list<CacheNode>::iterator > cacheMap;
};

  

5月18日:top10面试算法-LRUcache的实现的更多相关文章

  1. 深度学习DeepLearning技术实战(12月18日---21日)

    12月线上课程报名中 深度学习DeepLearning(Python)实战培训班 时间地点: 2020 年 12 月 18 日-2020 年 12 月 21日 (第一天报到 授课三天:提前环境部署 电 ...

  2. 2016年12月18日 星期日 --出埃及记 Exodus 21:13

    2016年12月18日 星期日 --出埃及记 Exodus 21:13 However, if he does not do it intentionally, but God lets it hap ...

  3. 2015年8月18日,杨学明老师《技术部门的绩效管理提升(研讨会)》在中国科学院下属机构CNNIC成功举办!

    2015年8月18日,杨学明老师为中国网络新闻办公室直属央企中国互联网络中心(CNNIC)提供了一天的<技术部门的绩效管理提升(研讨会)>培训课程.杨学明老师分别从研发绩效管理概述.研发绩 ...

  4. 2016年11月18日 星期五 --出埃及记 Exodus 20:9

    2016年11月18日 星期五 --出埃及记 Exodus 20:9 Six days you shall labor and do all your work,六日要劳碌作你一切的工,

  5. 2016年10月18日 星期二 --出埃及记 Exodus 19:2

    2016年10月18日 星期二 --出埃及记 Exodus 19:2 After they set out from Rephidim, they entered the Desert of Sina ...

  6. 天津Uber优步司机奖励政策(1月18日~1月24日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  7. 长沙Uber优步司机奖励政策(1月18日~1月24日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  8. 西安Uber优步司机奖励政策(1月18日~1月24日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  9. 上海Uber优步司机奖励政策(1月18日~1月24日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

随机推荐

  1. dede调用文章里的图片

    {dede:arclist row='6' orderby='pubdate' typeid='5' idlist='' channelid='1'} <li><a href='[f ...

  2. 一个最简html5文档来说明html5的新特性和写法

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8&quo ...

  3. [转载]SoapUI 参数化&数据库连接

    引用自 : http://www.cnblogs.com/liulinghua90/p/4954045.html 如果是没有代码能力的小白,要利用工具进行接口测试的时候,经常会遇到接口地址 或者接口参 ...

  4. think in java 读书笔记 1 ——移位

    目录 think in java 读书笔记 1 ——移位 think in java 读书笔记 2 —— 套接字 think in java 读书笔记 3 —— 数据报 在Think in Java中 ...

  5. ASP.NET Web API中的依赖注入

    什么是依赖注入 依赖,就是一个对象需要的另一个对象,比如说,这是我们通常定义的一个用来处理数据访问的存储,让我们用一个例子来解释,首先,定义一个领域模型如下: namespace Pattern.DI ...

  6. ocument的createDocumentFragment()方法

    在<javascript高级程序设计>一书的6.3.5:创建和操作节点一节中,介绍了几种动态创建html节点的方法,其中有以下几种常见方法: · crateAttribute(name): ...

  7. 【转】Session ID/session token 及和cookie区别

    Session + Cookie  知识收集! cookie机制采用的是在客户端保持状态的方案.它是在用户端的会话状态的存贮机制,他需要用户打开客户端的cookie支持.cookie的作用就是为了解决 ...

  8. Windows server2003 + sql server2005 集群配置安装

    http://blog.itpub.net/29500582/viewspace-1249319/

  9. js中获得当前时间是年份和月份

    js中获得当前时间是年份和月份,形如:201208       //获取完整的日期 var date=new Date; var year=date.getFullYear();  var month ...

  10. FZU 2092 收集水晶 bfs+记忆化搜索 or 暴力

    题目链接:收集水晶 一眼看过去,觉得是普通的bfs,初始位置有两个.仔细想了想...好像如果这样的话..........[不知道怎么说...T_T] dp[12][12][12][12][210] 中 ...