网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
举例:
//找到指向9的迭代器
list<int>::iterator findIter = find(list1.begin(), list1.end(), 9);
if (findIter == list1.end()) {
cout << " not found in list" << endl;
}
else {
cout << "found : "<<*findIter << endl;
}
//将指向9的迭代器移除并头插,之后findIter失效
list1.splice(list1.begin(), list1, findIter);
二、LRU catch
题目大意:设计一个用于LRU cache算法的数据结构。 题目链接。
分析:
为了保持cache的性能,使查找,插入,删除都有较高的性能,我们使用双向链表(std::list)和哈希表(std::unordered_map)作为cache的数据结构,因为:
双向链表插入删除效率高(单向链表插入和删除时,还要查找节点的前节点)
哈希表保存每个节点的地址,可以基本保证在O(1)时间内查找节点
具体实现细节:
- 越靠近链表头部,表示节点上次访问距离现在时间最短,尾部的节点表示最近访问最少。
- 查询或者访问节点时,如果节点存在,把该节点交换到链表头部(认为最近使用),同时更新hash表中该节点的地址
- 插入节点时,如果cache的size达到了上限,则删除尾部节点,同时要在hash表中删除对应的项。新节点都插入链表头部(认为最近使用)。
总结一下核心操作的步骤:
- put(key, value),首先在 HashMap 找到 Key 对应的节点,如果节点存在,更新节点的值,并把这个节点移动队头。如果不存在,需要构造新的节点,并且尝试把节点塞到队头,如果LRU空间不足,则通过 tail 淘汰掉队尾的节点,同时在 HashMap 中移除 Key。
- get(key),通过 HashMap 找到 LRU 链表节点,把节点插入到队头,返回缓存的值。
代码:
#include <bitset>
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <algorithm>
#include <unordered\_map>
using namespace std;
void printList(list<int> mylist)
{
list<int>::iterator iter = mylist.begin();
for (; iter != mylist.end(); ++iter)
{
cout << *iter << " ";
}
cout << endl;
}
struct CatchNode
{
int key;
int value;
CatchNode(int k, int v) :key(k), value(v) {}
};
class LRUCatche {
public:
LRUCatche(int capacity) {
size = capacity;
}
void put(int key, int value) {
if (catchMap.find(key) == catchMap.end()) //map中未找到
{
if (catchList.size() == size)
{
//容量满:删除链表尾部节点(最少访问节点)
catchMap.erase(catchList.back().key); //节点对应的键值
catchList.pop_back();
}
//插入新节点到链表头部,同时在map中更新?/插入该节点
catchList.push_front(CatchNode(key, value));
catchMap[key] = catchList.begin();
}
else //map中找到
{
//更新map中节点的值,在list中把当前节点移到链表头部,更新map中该节点的地址
catchMap[key]->value = value;
catchList.splice(catchList.begin(), catchList, catchMap[key]);
catchMap[key] = catchList.begin();
}
}
int get(int key)
{
//key未找到
if (catchMap.find(key) == catchMap.end())
return -1;
else
{
//在list中把当前访问节点移到链表头部,更新map中该节点的地址
catchList.splice(catchList.begin(), catchList, catchMap[key]);
catchMap[key] = catchList.begin();
return catchMap[key]->value;
}
}
private:
list<CatchNode> catchList;
unordered\_map<int,list<CatchNode>::iterator>catchMap;
![img](https://img-blog.csdnimg.cn/img_convert/d73a7c86fc2b10ef4ed4f884fc040b03.png)
![img](https://img-blog.csdnimg.cn/img_convert/707d5a5a0759d31742b4654eb2ae571c.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**
化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**