【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基本介绍 如下所示,是库里面对list的基本…...
正则表达式、常用的正则
文章目录 正则表达式字符含意义RegExp函数RegExp属性RegExp对象方法RegExp构造函数的第二个参数 常用的正则例子只包含数字(包括正数、负数、零)只包含中英文数字及键盘上的特殊字符校验密码是否符合规则的正则校验http或者https端口号的正则只校验端口号…...

ST官方基于米尔STM32MP135开发板培训课程(一)
本文将以Myirtech的MYD-YF13X以及STM32MP135F-DK为例,讲解如何使用STM32CubeMX结合Developer package实现最小系统启动。 1.开发准备 1.1 Developer package准备 a.Developer package下载: https://www.st.com/en/embedded-software/stm32mp1dev.ht…...

组件(lvs,keeplive,orm,mysql,分布式事务)
lvs LVS 已经集成到Linux内核系统中,ipvsadm 是 LVS 的命令行管理工具。 目前有三种 IP 负载均衡技术( VS/NAT 网络地址转换 、VS/TUN IP 隧道技术实现虚拟服务器 和 VS/DR 直接路由); 八种调度算法:轮询 …...
《视觉SLAM十四讲》报错信息和解决方案
文章目录 ch4-Sophus编译报错ch5/imageBasics安装opencv4.x报错ch5/joinMap/CMakeLists.txt编译报错ch5/joinMap-pcl_viewer map.pcd报错 ch4-Sophus编译报错 报错信息: error: lvalue required as left operand of assignmentunit_complex_.real() 1.;^~ error:…...
golang 设置http请求代理
tinypoxy 搭建http代理服务可参考:tinyproxy搭建http代理_wangxiaoangg的博客-CSDN博客 需求背景: 项目需要访问一国外服务接口,地址被墙。购买香港ecs服务器,并在上面搭建http代理服务。 一 使用http和https代理 func main() {pr…...

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

css实现水平居中
代码示例 <div class"box"><div class"box1"></div> </div>1.弹性布局:(推荐) display:flex; 这些要添加在父级的,是父级的属性 //父级添加display:flex; //父级添加jus…...

c刷题(一)
目录 1.输出100以内3的倍数 2.将3个数从大到小输出 3.打印100~200素数 方法一 方法二 4.显示printf的返回值 最大公约数 试除法 辗转相除法 九九乘法表 求十个数的最大值 1.输出100以内3的倍数 法一: int n 0; while (n*3 < 100){printf("%d &q…...
webpack
文章目录 webpack概念打包的场景为什么要打包在打包之外 - 翻译在打包之外 - 小动作 课程重点模块化利用立即执行函数来改变 作用域模块化的优点模块化方案的进化史AMD(成型比较早,应用不是很广泛)COMMONJSES6 MODULE webpack 的打包机制webp…...
反复 Failed to connect to github.com port 443 after xxx ms
前提:使用了代理,浏览器能稳定访问github,但git clone一直超时 解决方案: 1. git config --global http.proxy http://127.0.0.1:1080 2. 代理设置端口1080 3. 1080可自定义 感谢来自这篇博客和评论区的提醒:解决…...
ARM裸机-11
1、安装交叉编译工具工具 1.1、windows中装软件的特点 windows中装软件使用安装包,安装包解压后有两种情况:一种是一个安装文件 (.exe/.msi),双击进行安装,下一步直到安装完毕。安装完毕后会在桌面上生成快捷方式,我们平时使用快…...
centos7升级glibc
作者:吴业亮 博客:wuyeliang.blog.csdn.net 安装bison: yum install bison -y安装wget、bzip2、gcc、gcc-c和glibc-headers: yum -y install wget bzip2 gcc gcc-c glibc-headers安装make-4.2.1: wget http://ftp.…...
【OnnxRuntime】在linux下编译并安装C++版本的onnx-runtime
目录 安装C接口的onnx-runtime安装依赖项:下载源文件构建ONNX Runtime安装ONNX Runtime 安装C接口的onnx-runtime 安装依赖项: 安装CMake:可以通过包管理器(如apt、yum等)安装CMake。 安装C编译器:确保系…...
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:2. SUPPORTS:3. MANDATORY:4. REQUIRES_NEW:5. NOT_SUPPORTED:6. NEVER:7. NESTED: 二、事务传播机制分类1. 支持当前事务的传播机制:REQUIRE…...

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

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

docker 安装 字体文件
先说一下我当前的 场景 及 环境,这样同学们可以先评估本篇文章是否有帮助。 环境: dockerphp8.1-fpmwindows 场景: 来了个需求,有一个默认背景图,可以理解为背景图是一个 "相框",相框里面就会放…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...