当前位置: 首页 > news >正文

【C++从0到王者】第十四站:list基本使用及其介绍

文章目录

  • 一、list基本介绍
  • 二、list基本使用
    • 1.尾插头插接口使用
    • 2.insert接口使用
    • 3.查找某个值所在的位置
    • 4.erase接口使用以及迭代器失效
    • 5.reverse
    • 6.sort
    • 7.merge
    • 8.unique
    • 9.remove
    • 11.splice
  • 三、list基本使用完整代码

一、list基本介绍

如下所示,是库里面对list的基本介绍
在这里插入图片描述

链表是序列容器,允许在序列内的任何位置进行常量时间的插入和擦除操作,以及两个方向的迭代。

链表容器被实现为双链表;双链表可以将它们包含的每个元素存储在不同且不相关的存储位置。排序是通过与前面元素的链接和后面元素的链接的每个元素的关联在内部保持的。

它们与forward_list非常相似:主要区别在于forward_list对象是单链表,因此它们只能向前迭代,以换取更小和更高效。

与其他基本标准序列容器(array、vector和deque)相比,链表在容器内的任何位置插入、提取和移动元素(迭代器已经获得)方面通常表现更好,因此在大量使用链表的算法(如排序算法)中也表现更好。

与其他序列容器相比,列表和forward_lists的主要缺点是它们无法通过位置直接访问元素;例如,要访问链表中的第六个元素,必须从已知位置(如开始或结束)迭代到该位置,这需要在两者之间的距离上花费线性时间。它们还消耗一些额外的内存来保存与每个元素相关联的链接信息(对于包含小元素的大型列表来说,这可能是一个重要因素)。

在这里插入图片描述

二、list基本使用

我们先简单的使用一下一下list,list的使用与vector基本是一致的,需要注意的是,对于list是没有[]运算符去访问的,因为其底层是一个双向带头循环链表。

1.尾插头插接口使用

void testlist1()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.push_front(7);lt.push_front(8);list<int>::iterator it = lt.begin();while(it != lt.end()){cout << *it << " ";it++;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;
}

在这里插入图片描述

2.insert接口使用

从下面,我们已经看出来,对于list它的接口已经全部是迭代器去访问了,可以是在某个迭代器处插入一个值,可以是插入n个val,也可以是插入一个迭代器区间
在这里插入图片描述
在这里需要注意的是,由于list本身是一个链表的特性,所以如果想要在第五个位置插入一个值,以下写法是错误的。如果是vector确实可以这样插入
在这里插入图片描述

如果是我们自己去写这个list的话,我们可以加上这个运算符重载,但是库里面觉得这个代价太大,所以没有加

但是如果非要在第五个位置处插入,我们可以这样写,这样直接插入的代价是比较低的,因为其只需要改变连接关系即可

void testlist2()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int>::iterator it = lt.begin();for (int i = 0; i < 5; i++){it++;}lt.insert(it, 10);it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;
}

在这里插入图片描述

3.查找某个值所在的位置

其实在C++中list并没有直接提供这个接口,这是因为C++中是将容器和算法进行了分离。而这两个是通过迭代器进行连接起来的。
在这里插入图片描述

因为迭代器并不暴露容器底层的细节。就能让算法直接访问容器里面的元素。
在这里插入图片描述

注意库里面使用的是不等于,而非小于,这是为了适应其他各种各样的容器而设置的

比如list容器中,如果不采用这种设计结构,那么由于本来每个地址都是离散的,并不能确保每个结点的地址究竟是如何的,而产生严重的错误。
在这里插入图片描述

我们现在来使用一下

void testlist3()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int>::iterator pos = find(lt.begin(), lt.end(), 3);lt.insert(pos, 300);list<int>::iterator it = lt.begin();it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;
}

在这里插入图片描述

那么我们现在再来探讨一下,vector里使用insert后会存在失效问题,那么链表中还有吗。

我们可以测试一下

在这里插入图片描述

测试结果显示,迭代器并未失效,其实这里也挺好理解的,因为list的insert中它是一个结点一个结点的插入进去。而vector里则是看容量的,容量不够扩容时候,需要整体将空间移动位置,才导致的迭代器失效。而list不存在扩容问题。是不会将之前的数据都给换位置的。故而不导致迭代器失效。

4.erase接口使用以及迭代器失效

如下所示,erase可以删除某个迭代器位置的值,也可以删除某一个迭代器区间。
在这里插入图片描述

erase的使用很简单,我们这里主要研究以下,erase是否存在迭代器失效问题呢?其实是存在的,因为erase删除某一个结点后,由于list是离散的,所以之前的那个pos已经无法找到其他的结点的,这个迭代器已经是一个野指针了。故而失效。但是同样的库里面的解决方法就是增加一个返回值,返回已删除元素的下一个元素迭代器。
在这里插入图片描述

当我们想要删除所有的偶数的时候,我们也很容易的可以写出以下代码
在这里插入图片描述

5.reverse

注意了啊,这里是逆置,不是reserve(扩容)

这个接口的作用就是逆置链表
在这里插入图片描述

list里面虽然设计了这个接口,但是事实上这个接口是没有必要涉及的,有一点冗余,因为在算法库里面也设计了这个算法。而且这两个算法的思路是一模一样的
在这里插入图片描述

如下是测试代码

void testlist4()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);for (auto e : lt){cout << e << " ";}cout << endl;lt.reverse();for (auto e : lt){cout << e << " ";}cout << endl;reverse(lt.begin(), lt.end());for (auto e : lt){cout << e << " ";}cout << endl;
}

在这里插入图片描述

6.sort

如下是list里面的sort,可以直接排升序或者降序,使用很方便
在这里插入图片描述

但是算法库里面也设计了一个sort,但是这个是冗余的吗?先说结论,算法库里面的sort对于list而言是用不了的。会直接报错
在这里插入图片描述

不相信的话,我们可以测试一下
在这里插入图片描述
那么为什么用不了呢?我们可以深入去查看一下
我们从错误列表里面可以定位到是这里报错了
在这里插入图片描述

算法库里面使用的是快排,快排是无法适应list里面的这个场景的。

事实上,我们不难注意到,在算法库中,虽然每个算法都是一个函数模板,但是函数模板的迭代器名字有所差异
在这里插入图片描述

事实上,这是因为我们对迭代器从功能上进行了分类。注意这里的是由迭代器的性质(容器的底层结构决定的),从而进行的划分。他是一个隐式的划分
在这里插入图片描述

而上面的模板参数中对于迭代器的分类其实也显而易见了,Input就是所有迭代器都可以去用的。Bid这种迭代器就适合双向的迭代器去调用。Radom就适合随机迭代器去使用。

所以list适合双向迭代器,用不了随机的。

那么我们怎么知道哪个容器是哪种类型的呢?其实库里面已经全部说了

下面是list的迭代器
在这里插入图片描述

注意上面的不是彻底定死了,比如vector是随机迭代器,但他可以认为是特殊的双向迭代器。所以也是可以调用reverse接口的。
在这里插入图片描述
下面是vector的迭代器
在这里插入图片描述

再比如库里面也有单链表,forward_list,就是一个典型的单向迭代器
在这里插入图片描述

所以现在我们就清楚了为什么不能使用算法库里面的sort了,所以链表里面的sort就有点意义了。

当然呢,也只是有点意义罢了,其实也没有多大意义,为什么这么说呢?因为如果我们把list的数据拷贝给一个vector,然后用vector去排序,我们会发现,vector的效率远远高于list的效率

我们可以用如下代码去测试一下:注意需要在release环境下去测试,因为debug下有很多调试信息会影响两个的实际速度

void testlist5()
{srand(time(0));const int N = 1000000;vector<int> v; v.reserve(N);list<int> lt1;list<int> lt2;for (int i = 0; i < N; ++i){auto e = rand();lt2.push_back(e);lt1.push_back(e);}// 拷贝到vector排序,排完以后再拷贝回来int begin1 = clock();// 先拷贝到vectorfor (auto e : lt1){v.push_back(e);}// 排序sort(v.begin(), v.end());// 拷贝回去size_t i = 0;for (auto& e : lt1){e = v[i++];}int end1 = clock();int begin2 = clock();lt2.sort();int end2 = clock();printf("vector sort:%d\n", end1 - begin1);printf("list sort:%d\n", end2 - begin2);
}

在这里插入图片描述

可见确实vector要优于list。因为库里面用的是快排,list里面用的是归并。快排还是要稍微优于归并一点的。

7.merge

如下所示,它的作用其实就是两个链表进行归并,注意归并前必须先进行排序
在这里插入图片描述

// list::merge
#include <iostream>
#include <list>// compare only integral part:
bool mycomparison(double first, double second)
{return (int(first) < int(second));
}int main()
{std::list<double> first, second;first.push_back(3.1);first.push_back(2.2);first.push_back(2.9);second.push_back(3.7);second.push_back(7.1);second.push_back(1.4);first.sort();second.sort();first.merge(second);// (second is now empty)second.push_back(2.1);for (auto e : second){std::cout << e << " ";}std::cout << std::endl;first.merge(second, mycomparison);std::cout << "first contains:";for (std::list<double>::iterator it = first.begin(); it != first.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

如下是运行结果,我们可以发现一些现象,首先是归并之后,second的结点都被归并走了,它里面也就没有数据了。
注意,在第二次合并中,函数mycomparison没有考虑2.1比2.2或2.9低,因为进行了强制类型转换,所以它被插入到它们之后,在3.1之前。
在这里插入图片描述

8.unique

这个函数的功能是去重,但是要注意首先得先进行排序,才能进行去重。否则效率极低
在这里插入图片描述

9.remove

remove其实相当于find+erase。先找到要移除的结点,然后删除掉。
在这里插入图片描述如下代码所示

void testlist6()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);for (auto e : lt){cout << e << " ";}cout << endl;lt.remove(3);lt.remove(10);for (auto e : lt){cout << e << " ";}cout << endl;
}

找到3以后,移除掉这个结点,如果这个值不存在,即找不到,就什么也不做。
在这里插入图片描述

11.splice

这个是粘接、转移的意思,它可以将一个链表的某个结点拿走,交给另外一个链表
在这里插入图片描述

这三个函数的意思分别是,第一个函数是,将x链表全部转移到该链表的pos位置之前,第二个函数是将x链表的i结点转移到pos之前,第三个函数是,将x链表的某个迭代器区间,转移到pos之前。

如下代码所示,是该函数可以使用的情形

void testlist7()
{list<int> lt1;lt1.push_back(1);lt1.push_back(2);lt1.push_back(3);list<int> lt2;lt2.push_back(10);lt2.push_back(20);lt2.push_back(30);list<int> lt3;lt3.push_back(100);lt3.push_back(200);lt3.push_back(300);for (auto e : lt1){cout << e << " ";}	cout << endl;for (auto e : lt2){cout << e << " ";}cout << endl;list<int>::iterator it = lt1.begin();it++;lt1.splice(it, lt2);for (auto e : lt1){cout << e << " ";}cout << endl;list<int>::iterator it3 = lt3.begin();it3++;lt1.splice(it, lt3, it3);for (auto e : lt1){cout << e << " ";}cout << endl;lt1.splice(it, lt3, lt3.begin(), lt3.end());for (auto e : lt1){cout << e << " ";}cout << endl;it = lt1.begin();lt1.splice(it, lt1, ++lt1.begin(), lt1.end());for (auto e : lt1){cout << e << " ";}cout << endl;
}

在这里插入图片描述

三、list基本使用完整代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<algorithm>
#include<list>
#include<vector>
using namespace std;void testlist1()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.push_front(7);lt.push_front(8);list<int>::iterator it = lt.begin();while(it != lt.end()){cout << *it << " ";it++;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;
}
void testlist2()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int>::iterator it = lt.begin();for (int i = 0; i < 5; i++){it++;}lt.insert(it, 10);it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;
}
void testlist3()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int>::iterator pos = find(lt.begin(), lt.end(), 3);lt.insert(pos, 300);*pos *= 10;list<int>::iterator it = lt.begin();it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;//lt.erase(pos);//*pos = 10;it = lt.begin();while (it != lt.end()){if (*it % 2 == 0){it = lt.erase(it);}else{it++;}}it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;
}
void testlist4()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);for (auto e : lt){cout << e << " ";}cout << endl;lt.reverse();for (auto e : lt){cout << e << " ";}cout << endl;reverse(lt.begin(), lt.end());for (auto e : lt){cout << e << " ";}cout << endl;//sort(lt.begin(), lt.end());
}void testlist5()
{srand(time(0));const int N = 1000000;vector<int> v; v.reserve(N);list<int> lt1;list<int> lt2;for (int i = 0; i < N; ++i){auto e = rand();lt2.push_back(e);lt1.push_back(e);}// 拷贝到vector排序,排完以后再拷贝回来int begin1 = clock();// 先拷贝到vectorfor (auto e : lt1){v.push_back(e);}// 排序sort(v.begin(), v.end());// 拷贝回去size_t i = 0;for (auto& e : lt1){e = v[i++];}int end1 = clock();int begin2 = clock();lt2.sort();int end2 = clock();printf("vector sort:%d\n", end1 - begin1);printf("list sort:%d\n", end2 - begin2);
}void testlist6()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);for (auto e : lt){cout << e << " ";}cout << endl;lt.remove(3);lt.remove(10);for (auto e : lt){cout << e << " ";}cout << endl;
}
void testlist7()
{list<int> lt1;lt1.push_back(1);lt1.push_back(2);lt1.push_back(3);list<int> lt2;lt2.push_back(10);lt2.push_back(20);lt2.push_back(30);list<int> lt3;lt3.push_back(100);lt3.push_back(200);lt3.push_back(300);for (auto e : lt1){cout << e << " ";}	cout << endl;for (auto e : lt2){cout << e << " ";}cout << endl;list<int>::iterator it = lt1.begin();it++;lt1.splice(it, lt2);for (auto e : lt1){cout << e << " ";}cout << endl;list<int>::iterator it3 = lt3.begin();it3++;lt1.splice(it, lt3, it3);for (auto e : lt1){cout << e << " ";}cout << endl;lt1.splice(it, lt3, lt3.begin(), lt3.end());for (auto e : lt1){cout << e << " ";}cout << endl;it = lt1.begin();lt1.splice(it, lt1, ++lt1.begin(), lt1.end());for (auto e : lt1){cout << e << " ";}cout << endl;
}
int main()
{testlist7();return 0;
}//
// list::merge
//#include <iostream>
//#include <list>
//
// compare only integral part:
//bool mycomparison(double first, double second)
//{
//    return (int(first) < int(second));
//}
//
//int main()
//{
//    std::list<double> first, second;
//
//    first.push_back(3.1);
//    first.push_back(2.2);
//    first.push_back(2.9);
//
//    second.push_back(3.7);
//    second.push_back(7.1);
//    second.push_back(1.4);
//
//    first.sort();
//    second.sort();
//
//    first.merge(second);
//
//     (second is now empty)
//
//    second.push_back(2.1);
//    for (auto e : second)
//    {
//        std::cout << e << " ";
//    }
//    std::cout << std::endl;
//    first.merge(second, mycomparison);
//
//    std::cout << "first contains:";
//    for (std::list<double>::iterator it = first.begin(); it != first.end(); ++it)
//        std::cout << ' ' << *it;
//    std::cout << '\n';
//
//    return 0;
//}

好了,本期内容就到这里了

如果对你有帮助的话,不要忘记点赞加收藏哦!!!

相关文章:

【C++从0到王者】第十四站:list基本使用及其介绍

文章目录 一、list基本介绍二、list基本使用1.尾插头插接口使用2.insert接口使用3.查找某个值所在的位置4.erase接口使用以及迭代器失效5.reverse6.sort7.merge8.unique9.remove11.splice 三、list基本使用完整代码 一、list基本介绍 如下所示&#xff0c;是库里面对list的基本…...

正则表达式、常用的正则

文章目录 正则表达式字符含意义RegExp函数RegExp属性RegExp对象方法RegExp构造函数的第二个参数 常用的正则例子只包含数字&#xff08;包括正数、负数、零&#xff09;只包含中英文数字及键盘上的特殊字符校验密码是否符合规则的正则校验http或者https端口号的正则只校验端口号…...

ST官方基于米尔STM32MP135开发板培训课程(一)

本文将以Myirtech的MYD-YF13X以及STM32MP135F-DK为例&#xff0c;讲解如何使用STM32CubeMX结合Developer package实现最小系统启动。 1.开发准备 1.1 Developer package准备 a.Developer package下载&#xff1a; ‍https://www.st.com/en/embedded-software/stm32mp1dev.ht…...

组件(lvs,keeplive,orm,mysql,分布式事务)

lvs LVS 已经集成到Linux内核系统中&#xff0c;ipvsadm 是 LVS 的命令行管理工具。 目前有三种 IP 负载均衡技术&#xff08; VS/NAT 网络地址转换 、VS/TUN IP 隧道技术实现虚拟服务器 和 VS/DR 直接路由&#xff09;&#xff1b; 八种调度算法&#xff1a;轮询 …...

《视觉SLAM十四讲》报错信息和解决方案

文章目录 ch4-Sophus编译报错ch5/imageBasics安装opencv4.x报错ch5/joinMap/CMakeLists.txt编译报错ch5/joinMap-pcl_viewer map.pcd报错 ch4-Sophus编译报错 报错信息&#xff1a; error: lvalue required as left operand of assignmentunit_complex_.real() 1.;^~ error:…...

golang 设置http请求代理

tinypoxy 搭建http代理服务可参考&#xff1a;tinyproxy搭建http代理_wangxiaoangg的博客-CSDN博客 需求背景&#xff1a; 项目需要访问一国外服务接口&#xff0c;地址被墙。购买香港ecs服务器&#xff0c;并在上面搭建http代理服务。 一 使用http和https代理 func main() {pr…...

我的会议(会议通知)

前言: 我们在实现了发布会议功能&#xff0c;我的会议功能的基础上&#xff0c;继续来实现会议通知的功能。 4.1实现的特色功能&#xff1a; 当有会议要参加时&#xff0c;通过查询会议通知可以知道会议的内容&#xff0c;以及当前会议状态&#xff08;未读&#xff09; 4.2思路…...

css实现水平居中

代码示例 <div class"box"><div class"box1"></div> </div>1.弹性布局&#xff1a;&#xff08;推荐&#xff09; display:flex&#xff1b; 这些要添加在父级的&#xff0c;是父级的属性 //父级添加display:flex; //父级添加jus…...

c刷题(一)

目录 1.输出100以内3的倍数 2.将3个数从大到小输出 3.打印100~200素数 方法一 方法二 4.显示printf的返回值 最大公约数 试除法 辗转相除法 九九乘法表 求十个数的最大值 1.输出100以内3的倍数 法一&#xff1a; int n 0; while (n*3 < 100){printf("%d &q…...

webpack

文章目录 webpack概念打包的场景为什么要打包在打包之外 - 翻译在打包之外 - 小动作 课程重点模块化利用立即执行函数来改变 作用域模块化的优点模块化方案的进化史AMD&#xff08;成型比较早&#xff0c;应用不是很广泛&#xff09;COMMONJSES6 MODULE webpack 的打包机制webp…...

反复 Failed to connect to github.com port 443 after xxx ms

前提&#xff1a;使用了代理&#xff0c;浏览器能稳定访问github&#xff0c;但git clone一直超时 解决方案&#xff1a; 1. git config --global http.proxy http://127.0.0.1:1080 2. 代理设置端口1080 3. 1080可自定义 感谢来自这篇博客和评论区的提醒&#xff1a;解决…...

ARM裸机-11

1、安装交叉编译工具工具 1.1、windows中装软件的特点 windows中装软件使用安装包&#xff0c;安装包解压后有两种情况:一种是一个安装文件 (.exe/.msi)&#xff0c;双击进行安装&#xff0c;下一步直到安装完毕。安装完毕后会在桌面上生成快捷方式&#xff0c;我们平时使用快…...

centos7升级glibc

作者&#xff1a;吴业亮 博客&#xff1a;wuyeliang.blog.csdn.net 安装bison&#xff1a; yum install bison -y安装wget、bzip2、gcc、gcc-c和glibc-headers&#xff1a; yum -y install wget bzip2 gcc gcc-c glibc-headers安装make-4.2.1&#xff1a; wget http://ftp.…...

【OnnxRuntime】在linux下编译并安装C++版本的onnx-runtime

目录 安装C接口的onnx-runtime安装依赖项&#xff1a;下载源文件构建ONNX Runtime安装ONNX Runtime 安装C接口的onnx-runtime 安装依赖项&#xff1a; 安装CMake&#xff1a;可以通过包管理器&#xff08;如apt、yum等&#xff09;安装CMake。 安装C编译器&#xff1a;确保系…...

C#基于OpenCv(OpenCvSharp) 的 fftshift, ifftshift 函数的实现

本文实现基于OpenCv(OpenCvSharp) 的 fftshift, ifftshift 函数。 fftshift 函数将信号频谱的零频分量移动到数组中心, 本质是分别对调一三象限数据。 ifftshift完成相反的操作,本质是二四象限的数据块。 OpenCV中没有这两个函数如果使用需要自己实现。 实现代码如下: …...

【SpringBoot】笔记2

文章目录 45、web实验-抽取公共页面46、web实验-遍历数据与页面bug修改47、视图解析-【源码分析】-视图解析器与视图[暂时没看]48、拦截器-登录检查与静态资源放行49、拦截器-【源码分析】-拦截器的执行时机和原理50、文件上传-单文件与多文件上传的使用51、文件上传-【源码流程…...

Spring事务传播机制详细讲解

文章目录 一、事务传播机制1. REQUIRED&#xff1a;2. SUPPORTS&#xff1a;3. MANDATORY&#xff1a;4. REQUIRES_NEW&#xff1a;5. NOT_SUPPORTED&#xff1a;6. NEVER&#xff1a;7. NESTED&#xff1a; 二、事务传播机制分类1. 支持当前事务的传播机制&#xff1a;REQUIRE…...

kubernetes 集群搭建(kubeadm 方式)

目前生产部署 Kubernetes 集群主要有两种方式&#xff1a; &#xff08;1&#xff09; kubeadm Kubeadm 是一个 Kubernetes 官方提供的命令行工具&#xff0c;可以用来部署和管理 Kubernetes 集群。它主要用于在新的 Kubernetes 环境中初始化集群、添加或删除节点等操作。 K…...

基于ARM+FPGA的驱控一体机器人控制器设计

目前市场上工业机器人&#xff0c;数控机床等多轴运动控制系统普遍采用运动控制器加 伺服驱动器的分布式控制方式。在这种控制方式中&#xff0c;控制器一方面完成人机交互&#xff0c;另 一方面进行 NC 代码的解释执行&#xff0c;插补运算&#xff0c;继而将计算出来的位…...

docker 安装 字体文件

先说一下我当前的 场景 及 环境&#xff0c;这样同学们可以先评估本篇文章是否有帮助。 环境&#xff1a; dockerphp8.1-fpmwindows 场景&#xff1a; 来了个需求&#xff0c;有一个默认背景图&#xff0c;可以理解为背景图是一个 "相框"&#xff0c;相框里面就会放…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...