c++的STL(4)-- list容器

list容器概述

  • list的容器的实现是使用双向链表的形式的数据结构实现的。(也有的编译器使用双向循环链表

  • 链表是一种数据结构,这种结构与数组的结构不同,链表的每个节点都存放有特定个数的指针(双向链表:两个(一个指向前面的元素,另一个指向后面的元素),普通的链表:一个(指向后面的元素))。
  • 链表中的数据也不是连续的,也就是说它们的物理内存中不是挨着的这样链表就不用局限于空间不够的情况,只要内存中有位置,它可以在任意位置创建节点,存放数据,只要使用上一个或者下一个节点的指针存放这个内存的地址就行
  • 由于这样的结构,链表就不能像数组一样,随机存取数据了(简单来说,使用[]或者at()访问数据)。

数组是由于内存连续,所以我们可以根据首地址+偏移值就很快找到相应位置了

链表其存储的数据是不连续的,我们想要找到下一个数据存储的位置需要根据上一个节点中记录的位置来找到它。 -->  所以我们找一个数据,需要从最开始一个一个往后找。

  • 鉴于链表这种存储数据的结构,list容器在添加和删除数据的时候很快,但是在存取数据的时候,由于需要从头开始遍历寻找,所以很慢。 所以,当我们的场景是需要多次插入删除,但是很少存取元素的时候,建议使用list容器。
  • 而且使用list容器插入和删除数据的时候,不会影响到别的数据,只需要将对应的指针进行修改就行。
  • 所以,注意在list容器中开辟内存时,是需要多少开辟多少,什么时候需要再开辟,是不会像vector一样提前开辟,list提前开辟相当于一种浪费。

要使用list容器需要导入头文件#include<list> 

1. list容器的默认构造 

 代码

/*list<int> l1;list<float> l2;list<Student> l3;list<int*> l4;list<Student*>l5;
*/

2. list容器的有参构造 

代码

/*int arr[] = { 1,2,3,4,5 };vector<int> v1{ 10,11,12,,13,14,15,16 };// 第一种:  开始l1容器具有10个元素,并且元素值为类型默认值(int的默认值为0)list<int> l1(10);// 第二种:  开始l2容器具有10个元素,并且元素值为5list<int> l2(10, 5);// 第三种:  开始l3容器中具有初始化列表中的元素list<int> l3{ 1,2,3,4,5 };// 第四种:  开始l4容器中具有l3的全部元素list<int> l4(l3.begin(), l3.end());// 第五种:  拷贝构造函数list<int> l5(l3);// 第六种:  开始l6容器中具有数组第二个---第四个元素list<int> l6(arr + 1, arr + 5);// 第七种:  开始l7中具有v1容器中的全部元素list<int> l7(v1.begin(), v1.end());
*/
相关知识点: 
  • list<类型> l1(n);  // l1开始就有n个元素,并且值为类型默认值
  • list<类型> l1(n,elem);  // l1开始就有n个元素,并且值为elem
  • list<类型> l1(l2);  // 拷贝构造函数
  • list<类型> l1({data...});  // 开始l1就拥有初始化列表中的元素
  • list<类型> l1(beg,end); // 在左闭右开的迭代器范围内的数据放入l1。(可以为其它容器的迭代器)
  • list<类型> l1(ptr1,ptr2); // 在左开右闭的指针区间内的数据放入l1。(一般指定数组中数据的范围)

3. list容器尾部添加和删除元素(和deque的使用方法类似) 

代码 

/*list<int> l1;// 添加元素l1.push_back(1);l1.push_front(2);l1.emplace_back(3);l1.emplace_front(4);// 删除元素l1.pop_back();l1.pop_front();
*/

4. list容器的元素个数

代码 

	list<int> l1{10,11,12,13,14,15};cout << "l1容器的元素个数: " << l1.size() << endl;  // 元素个数为6

5.在指定位置插入元素 

 代码:使用insert()函数

	list<int> l1;list<int> l2{ 1,2,3,4,5 };vector<int> v1{10,11,12,13,14,15};// 一. 使用insert// 方式一:l1.insert(l1.begin(), 5);// 方式二:l1.insert(l1.begin(), 5, 3);// 方式三:l1.insert(l1.begin(), l2.begin(), l2.end());  // 使用相同容器l1.insert(l1.begin(), v1.begin(), v1.end());  // 使用不同容器// 方式四:l1.insert(l1.begin(), { 5,6,7,8,9 });// 二. 使用emplacel1.emplace(l1.begin(), 5);
相关知识点: 
  • 和deque的用法是类似的。 
  • insert在插入多个元素和单个元素时候,会返回一个直系那个插入位置的迭代器。(不同的编译器实现可能不一样)
  • 使用insert()函数,将一个list(l1)中的元素添加到另外一个list(l2)容器中,不会影响l1中的数据。

 

代码:  使用splice()函数 

	/*splice 的多种重载形式1. l1.splice(l1.begin(),l2, l2.begin(),++l2.begin());  // 将l2中[beg,end)范围内的元素 添加到l1的开始位置2. l1.splice(l1.begin(),l2);  // 将l2的全部数据添加到l1的开始位置3. l1.splice(l1.begin(), l2, ++l2.begin()); // 将l2中第二个元素放到l1的开始位置4. l1.splice(l1.begin(), list<int>{1,2,3}); // 将匿名对象中的元素放到l1的开始位置5. l1.splice(l1.begin(),{1,2,3});  // 同上*/int main(void) {list<int> l1{ 10,20,30,40,50};list<int> l2{ 1,2,3,4,5 };l1.splice(l1.begin(), l2,l2.begin());  // 将l2的第一个元素放到l1的开始位置cout << "l1中的元素:" << endl;for (list<int>::iterator it = l1.begin(); it != l1.end(); it++) {cout << *it << " ";  }cout << endl;cout << "l2中的元素:" << endl;for (list<int>::iterator it = l2.begin(); it != l2.end(); it++) {cout << *it << " ";}cout << endl;system("pause");return 0;
}

结果: 

 

相关知识点 
  • splice(list1.loc,list2); //  将list2中的元素拼接到list1的loc位置。
  • splice(list1.loc,list2,list2.loc); // 将list2中loc位置的元素拼接到list1的loc位置
  • splice(list1.loc,list2,list2.beg,list2.end); // 将list2[beg,end)范围内的元素拼接到list1的loc位置
  • splice(list1.loc,{data...}); // 将data中的数据拼接到list1的loc位置。
注意事项 

splice函数添加数据和insert函数不同,splice函数会影响第二个list中的元素。

仔细观察上面的输出,会发现我们将l2中的第二个数据添加到l1中,l2中的这个数据就没有了。

这是为什么呢? 

这其实和list的内部实现使用链表是有关系的,注意我们在介绍splice的时候,使用的是拼接而不是添加。

图解splice的过程:

list的底层是使用链表实现的,链表的内存不连续,使用指针维系先后关系。 

 

此时我们使用splice函数将list2中的2拼接到list1的开头。 

如图,我们会发现在list1中添加list2中的第二个元素,并不是像insert一样,在list1中添加一个和list2对应元素相同的数据。而是改变list1和list2的指针指向。

将list2中本来第一个元素指向的下一个元素是2,因为我们使用splace将2拼接到list1中了,所以list2中的第一个元素的下一个元素,就是2对应的元素的下一个元素,也就是3。

与list2一样,list1就是将list2中解放出来的元素中指针,指向list1中当前的第一个元素。

所以,使用splice()函数的时候,是会影响list2中的元素的因为它是直接改变对应元素的指针的指向,将list2中的元素链接到list1中,这样这个元素就变成list1中的元素了。(list2中这个元素就没有了)

 

代码: 使用merge()函数 

int main(void) {list<int> l1{ 1,2,30,40,50};list<int> l2{ 1,2,3,4,5 };/*list2.merge(list1);  将list1中的元素,根据其在list2中的大小顺序拼接到list2中list2.merge(list1,函数对象);  与上面类似,但是我们可以参数2指定拼接规则*/l1.merge(l2);cout << "l1中的元素:" << endl;for (list<int>::iterator it = l1.begin(); it != l1.end(); it++) {cout << *it << " ";  }cout << endl;cout << "l2中的元素:" << endl;for (list<int>::iterator it = l2.begin(); it != l2.end(); it++) {cout << *it << " ";}cout << endl;system("pause");return 0;
}

结果: 

 

相关知识点 
  • list2.merge(list1);  // 将list1中的元素根据其在list2中的大小关系拼接到list2中。(默认是从小到大)

例:  list1:  1,2,3   list2: 1,5,6   list2.merge(list1)之后, list1:  空,  list2: 1,1,2,3,5,6。

  • list2.merge(list1,函数对象);  //作用和上面类似,只不过是拼接规则我们来指定 
注意事项: 
  • 使用merge()进行拼接时,两个容器中的元素必须都符合拼接规则。否则程序中断。

比如:  我们要求从小到大拼接, 那么list1和list2中的元素也必须是从小到大的。

  • 如果我们只传入一个参数,那么就默认从小到大拼接。 因为内部会调用less函数对象类(就是c++内部实现的一个函数对象类,(要求传入两个参数n1,n2,n1<n2返回true),在此处表示从小到大排的)
  • 我们也可以传入使用list2.merge(list1,greater<类型>())(传入一个greater类的匿名对象,因为less和greater都是类模板,所以使用是要传入类型参数), 来实现从大到小拼接,但是这样,list1和list2中的元素也必须是从大到小的。
  • greater和less一样,都是内部实现的函数对象,只不过greater和less相反,当n1>n2时返回true。(在此处表示从大到小拼接)
  • 当然我们可以在第二个参数传入我们自定义的函数对象来指定拼接规则。
  • 使用merge()进行拼接和splice()一样,都会影响list1中的元素。

6. list容器元素的访问(注意有变化)

注意

前面说到,list的内部是以链表的形式实现的,所以它与vector和deque不同,它是不能使用下标来访问数据的(也就是[]和at())。 

 代码

list<int> l2{ 1,2,3,4,5 };// 使用front()获取第一个元素,并可以将其修改
l2.front() = 10;
cout << l2.front() << endl;// 使用back()获取最后一个元素,并可以将其修改
l2.back() = 20;
cout << l2.back() << endl;// 还有就是使用迭代器,我们后面说
 相关知识点
  •  除注意事项外,其它的和deque是类似的。

7. list容器迭代器的使用(注意有变化)

 注意

迭代器我们可以看做指针,它是用来遍历容器用的。

对于list容器,其迭代器除++,--之外不能进行任何的运算操作(比如: it+1, it+5, it1+it2 , it2-it1等)。而且也不能进行比较(>,<,=等)

原因就是因为,list的底层结构是用链表来实现的,它的内存不是连续的,你对指针或者迭代器+1等,其也是根据指针或者迭代器所在位置,偏移相应的字节来使其指向下一个位置,但是链表的内存不连续,指不定存哪呢,你怎么知道偏移多少,所以不允许。

那为什么++,--可以,此处的++,--你可以理解成其指定了迭代器的方向,++表示迭代器向后,--表示向前。其内部进行了操作,是可以找到下一个元素的。

只使用++,--也能体现出链表在访问数据时,需要一个一个找。

至于为什么不能比较,因为其指向的内存可能相差很多,你用它们比较没有意义。(vector和deque的可以比较,因为其内存是连续的)

代码 

list<int> l2{ 1,2,3,4,5,6,7,8,9,10};list<int>::iterator it1 = l2.begin();
it1++;
it1++;list<int>::iterator it2 = l2.end();// 遍历数据
while (it1 != it2) {cout << *it1 << " ";   // 3 4 5 6 7 8 9 10it1++;
}
相关知识点: 
  • 除去注意中的,其它的都和deque类似。 
  • 对于rbegin,cbegin,crbegin等在vector中已经演示。

8. list容器删除元素(有新增)

 代码: erase()和clear()

list<int> l2{ 1,2,3,4,5,6,7,8,9,10};// 一.erase的两种用法
// 删除指定位置的元素
l2.erase(l2.begin());// 删除规定范围内的元素
list<int>::iterator it = l2.begin();
it++;
it++;
l2.erase(it, l2.end());// 二.clear的用法:  清空元素
l2.clear();for (list<int>::iterator it = l2.begin(); it != l2.end(); it++) {cout << *it << " ";
}
cout << endl;
相关知识点: 
  • 对于erase和clear函数的使用,和deque是类似的。
  • 在erase和循环结合删除指定元素的时候,应该注意迭代器的更新的问题。-- 使用erase函数的返回值(在vector中已经演示过了) 

代码:使用remove()函数 

	list<int> l2{ 1,1,2,3,55,1,1,1,6,5};l2.remove(1);for (list<int>::iterator it = l2.begin(); it != l2.end(); it++) {cout << *it << " ";  // 输出2,3,55,6,5}cout << endl;
相关知识点: 
  • remove(nub);  // 用于删除list容器中所有与nub值相同的元素。 

代码: remove_if()函数 

class Compare1 {
public:bool operator()(int n1) {return n1 >= 5;  // 将大于等于5的元素都删除掉}
};int main(void) {list<int> l2{ 6,6,6,4,5,4,3,2,7,9,10};l2.remove_if(Compare1());system("pause");return 0;
}

结果:  

 

相关知识点: 
  • remove_if()函数,用于删除满足条件的元素。
  • 这是一个函数模板, 它接收一个类对象用来指定删除元素的条件。编译器会根据传入实参的类型,来实例化类参数

使用一个类对象来指定某种规则(此处为删除元素的规则),我们使用函数对象来指定。

Compare1是一个函数对象类,其指定了删除元素的规则(将list容器中>=5的元素删除掉,当传入元素>=5,()重载函数返回true,那么就删除此元素)。

我们在remove_if()中传入一个临时对象,函数内部会使用函数对象来调用()重载方法,来判断一个元素是否应该被删除。

 

代码:  unique()函数 

int main(void) {list<int> l2{ 6,6,6,4,5,4,3,2,2,7,9,10};l2.unique();for (list<int>::iterator it = l2.begin(); it != l2.end(); it++) {cout << *it << " ";  }cout << endl;system("pause");return 0;
}

结果: 

 

 

代码:  使用unique(参数)函数

class uniqueClass {
public:bool operator()(int a, int b) {return a!=b;}
};int main(void) {list<int> l2{ 6,6,6,4,5,4,3,2,2,7,9,10};l2.unique(uniqueClass());for (list<int>::iterator it = l2.begin(); it != l2.end(); it++) {cout << *it << " ";  }cout << endl;system("pause");return 0;
}

结果: 

 

相关知识点: 
  • unique()函数,如果不写参数,这个函数用于将存储在列表中的数据,如果相邻的元素有相同的,那么只保留其中的一个元素,将其它的相同的都删除掉。(注意:  必须是相邻的元素,不相邻的不会)。 
  • unique(参数)函数,传入函数对象,用来指定unique的删除规则。上面代码中,我们传入了自定义的规则,如果相邻的元素不相同,则删除元素。 --  可以根据自己的需求定义删除规则。

 

unique删除过程: (图解) 

删除相邻的相同元素:

最开始,会比较前两个数据,如果后面的等于前面的,那就将后面的元素删除。 

第一个元素与第二个元素相同,则删除第二个元素,然后第一个元素再和第三个元素进行比较,判断是否相同。

 

如果第一个元素和第三个元素不相同,那么就跳过当前数据,让第三个元素和第四个元素进行相比。以此类推,知道判断结束

 

删除相邻的不同元素:(也就是我们代码中自定义的删除方式,也可以定义别的) 

判断第一个元素和第二个元素是否不同,如果不同就删除后面的元素,如果相同,就使用第二个元素和第三个元素进行比较。

 

第二个元素和第三个元素比相同,那么删除第三个元素,第二个元素再和第四个元素比较,以此类推,知道判断完所有的元素。 (所以第二个代码的结果为666)

9. list容器的排序函数 

代码: sort() 

int main(void) {list<int> l1{ 5,4,3,2,1};/*sort();   // 默认将list中的元素按照从小到大排序sort(函数对象); // 将元素按照函数对象指定的规则排序*/l1.sort();//l1.sort(greater<int>());cout << "l1中的元素:" << endl;for (list<int>::iterator it = l1.begin(); it != l1.end(); it++) {cout << *it << " ";  }cout << endl;system("pause");return 0;
}

结果: 

 

 相关知识点
  • sort();  // 将list中的元素默认按照从小到大的顺序排列。(其实就是默认使用less函数对象) 
  • sort(函数对象); // 将list中的元素按照函数规则指定的规则进行排列。

我们使用greater给出实例:   sort(greater<int>());   

 

10. list容器数据翻转

代码: reverse()函数

int main(void) {list<int> l1{ 5,4,3,2,1,6};/*reverse()将lsit容器中的元素进行翻转*/l1.reverse();cout << "l1中的元素:" << endl;for (list<int>::iterator it = l1.begin(); it != l1.end(); it++) {cout << *it << " ";  }cout << endl;system("pause");return 0;
}

结果: 

 

相关知识点: 
  • reverse();  // 将list容器中的元素进行翻转。 

 

10.list的其它函数 

代码:  swap()函数,交换两容器的数据 

int main(void) {list<int> l1{ 5,4,3,2,1,6};list<int> l2{ 10,11,12 };l1.swap(l2);cout << "l1中的元素:" << endl;for (list<int>::iterator it = l1.begin(); it != l1.end(); it++) {cout << *it << " ";  }cout << endl;cout << "l2中的元素:" << endl;for (list<int>::iterator it = l2.begin(); it != l2.end(); it++) {cout << *it << " ";}cout << endl;system("pause");return 0;
}

结果: 

 

 

 代码:  max_size()(和前面容器类似)

int main(void) {list<int> l1{ 5,4,3,2,1,6};cout << l1.max_size() << endl;  // 768614336404564650system("pause");return 0;
}

代码:  resize()函数 

和deque和vector类似,所以就不在展示了。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/742847.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百度现在应该怎么去做搜索SEO优化?(川圣SEO)蜘蛛池

baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; 百度搜索引擎优化&#xff08;SEO&#xff09;是一种通过优化网站&#xff0c;提升网页在百度搜索结果中的排…

使用Golong轻松实现JWT身份验证

使用Golong轻松实现JWT身份验证 JSON Web Tokens (JWT)是一种流行的安全方法&#xff0c;用于在两个方之间表示声明。在Web应用程序领域&#xff0c;它们通常用作从客户端向服务器传输身份信息&#xff08;声明&#xff09;的方式。本教程将引导您逐步实现Go应用程序中的JWT身份…

开源生态与软件供应链研讨会

✦ 日程安排 开源生态与软件供应链研讨会 时间: 2024年3月12日&#xff08;星期二&#xff09;13:30 – 17:00 地点: 复旦大学江湾校区二号交叉学科楼E1021 联系人: 陈碧欢&#xff08;bhchenfudan.edu.cn&#xff09; 点击文末“阅读原文”或扫描下方二维码进入报名通…

2024 前端javaScript+ES6

JavaScript 基础 1、基本数据类型&#xff1a; 1.1 基本数据类型&#xff1a; Number&#xff08;数值&#xff09;&#xff1a;表示数字&#xff0c;包括整数和浮点数。例如&#xff1a;5、3.14。 String&#xff08;字符串&#xff09;&#xff1a;表示文本数据&#xff…

视觉图像处理和FPGA实现第三次作业--实现一个加法器模块

一、adder模块 module adder(ina, inb, outa); input [5:0] ina ; input [5:0] inb ; output [6:0] outa ;assign outa ina inb; endmodule二、add模块 module add(a,b,c,d,e); input [5:0] a ; input [5:0] b ; input [5:…

PTA L2-020 功夫传人

一门武功能否传承久远并被发扬光大&#xff0c;是要看缘分的。一般来说&#xff0c;师傅传授给徒弟的武功总要打个折扣&#xff0c;于是越往后传&#xff0c;弟子们的功夫就越弱…… 直到某一支的某一代突然出现一个天分特别高的弟子&#xff08;或者是吃到了灵丹、挖到了特别的…

从零开始,一步步构建服务网格istio

一、环境情况 环境&#xff1a;Ubuntu20.04 机器数量&#xff1a;单机1台 IP&#xff1a;10.9.2.83 二、准备知识 为什么使用 Istio&#xff1f; Istio提供了一种更高级别的服务网格解决方案&#xff0c;它可以简化和加强 Kubernetes 集群中的服务间通信、流量管理、安全…

鸿蒙开发之MPChart图表开发

一、简介 随着移动应用的不断发展,数据可视化成为提高用户体验和数据交流的重要手段之一,因此需要经常使用图表,如折线图、柱形图等。OpenHarmony提供了一个强大而灵活的图表库是实现这一目标的关键。 在 ohpm 中心仓(https://ohpm.openharmony.cn/)中,汇聚了众多开发者…

ubuntu如何添加快捷方式到收藏夹、桌面

一、背景 有时候单独下载的软件包需要在特定路径里启动&#xff0c;这样使用起来非常不方便。因此需要在桌面和收藏夹里创建启动快捷方式。 二、具体步骤 这里以下载的zotero软件&#xff08;一款用于文献管理的软件&#xff09;为例。官网地址: Zotero | Your personal res…

【gpt实践】同时让chatgpt和claude开发俄罗斯方块

最近chatgpt和claude都在使用&#xff0c;其实大部分日常使用场景表现都没有相差太多&#xff0c;想搞一个有趣的小实验&#xff0c;如果同时让chatgpt和claude开发俄罗斯方块谁会表现的更好呢&#xff0c;说干就干&#xff01; prompt 我选择了用英文描述&#xff0c;毕竟英…

《如何使用C语言去下三子棋?》

目录 一、环境配置 二、功能模块 1.打印菜单 2.初始化并打印棋盘 3、行棋 3.1玩家行棋 3.2电脑行棋 4、判断是否和棋 5.判赢 三、代码实现 1、test.c文件 2、game.c文件 3、game.h文件 一、环境配置 本游戏用到三个文件&#xff0c;分别是两个源文件test.c game.c 和…

cad转shp再转3dtiles生成白模

1、准备CAD数据 2、arcgis中添加cad数据 添加面 cad中的标高字段是能带进arcgis中的&#xff0c;如果这个数据是建筑高度&#xff0c;可以直接用了 3、转shp 4、shp转3dtiles白模 cesiumlab中shp转3dtiles白模效果一

Spring Cloud Alibaba微服务从入门到进阶(三)

Spring Cloud Alibaba是spring Cloud的子项目 Spring Cloud Alibaba的主要组件&#xff08;红框内是开源的&#xff09; Spring Cloud是快速构建分布式系统的工具集&#xff0c; Spring Cloud提供了很多分布式功能 Spring Cloud常用子项目 项目整合 Spring Cloud Alibaba …

搭建项目后台系统基础架构

任务描述 1、了解搭建民航后端框架 2、使用IDEA创建基于SpringBoot、MyBatis、MySQL、Redis的Java项目 3、以原项目为参照搭建项目所涉及到的各个业务和底层服务 4、以原项目为例&#xff0c;具体介绍各个目录情况并参照创建相关文件夹 1、创建项目后端 BigData-KongGuan …

海豚调度系列之:任务类型——SQL节点

海豚调度系列之&#xff1a;任务类型——SQL节点 一、SQL节点二、创建任务三、任务参数四、任务样例五、运行该任务成功之后在hive中查询结果六、使用前置sql和后置sql示例 一、SQL节点 SQL任务类型&#xff0c;用于连接数据库并执行相应SQL。 二、创建任务 点击项目管理-项…

清廉机关建设宣传稿件怎样联系媒体投稿发表?

在推进清廉机关建设的伟大征程中,我们深知信息宣传的重要性。如何将清廉机关建设的成果和理念广泛传播,让更多人了解并参与到这一伟大事业中来,成为我们面临的重要课题。 过去,我们或许曾经历过联系媒体投稿的种种心酸。一家家媒体的联系,一次次的等待与回复,其中的艰辛与不易…

春风吹又生的开源项目「GitHub 热点速览」

随着上周知名 Switch 开源模拟器 Yuzu&#xff08;柚子&#xff09;被任天堂起诉&#xff0c;该项目作者就删库了&#xff0c;但还是要赔偿任天堂数百万美元。此事还在 GitHub 上掀起了一波 Yuzu fork 项目的小浪潮&#xff0c;正所谓野火烧不尽&#xff0c;春风吹又生。 很多读…

Unity使用Addressable热更新

先看热更新的gif: Addressable是Unity推出的打ab包方案。不需要手动写AB打包脚手架了&#xff0c;不需要关心依赖&#xff0c;这也简化了ab热更新的流程。Addressable打包需要先将资源放入group中&#xff0c;按group来打包&#xff0c;每个group对应一个ScriptableObject的配置…

大模型学习笔记(一):部署ChatGLM模型以及stable-diffusion模型

大模型学习笔记&#xff08;一&#xff09;&#xff1a;部署ChatGLM模型以及stable-diffusion模型 注册算力平台&#xff08;驱动云平台&#xff09;1.平台注册2.查看算力3.进入平台中心 部署ChatGLM3-6B模型1.创建项目2.配置环境设置镜像源、克隆项目修改requirements 3.修改w…

【git报错】【重置代理】Failed to connect to github.com port 443: Connection refused

重置代理 git config --global --unset http.proxy git config --global --unset https.proxy