C++初阶-list的使用2
目录
1.std::list::splice的使用
2.std::list::remove和std::list::remove_if的使用
2.1remove_if函数的简单介绍
基本用法
函数原型
使用函数对象作为谓词
使用普通函数作为谓词
注意事项
复杂对象示例
2.2remove与remove_if的简单使用
3.std::list::unique的使用
3.1std::list::unique的第二个函数的简单介绍
基本语法
基本示例
使用函数对象作为谓词
处理自定义类型
注意事项
3.2std::list::unique函数的使用
4.std::list::merge的使用
5.std::list::sort函数以及std::sort(list)的使用
6.C++迭代器(非常重要)
1. 输入迭代器 (input_iterator_tag)
2. 输出迭代器 (output_iterator_tag)
3. 前向迭代器 (forward_iterator_tag)
4. 双向迭代器 (bidirectional_iterator_tag)
5. 随机访问迭代器 (random_access_iterator_tag)
6.每个容器所对应的迭代器以及注意事项
1. 序列容器 (Sequence Containers)
std::array
std::vector
std::deque (双端队列)
std::list (双向链表)
std::forward_list (单向链表)
2. 关联容器 (Associative Containers)
std::set/std::multiset
std::map/std::multimap
3. 无序关联容器 (Unordered Associative Containers)
std::unordered_set/std::unordered_multiset
std::unordered_map/std::unordered_multimap
4. 容器适配器 (Container Adaptors)
std::stack 和 std::queue
特殊迭代器
std::string
std::string_view
迭代器类别对算法的影响
7.简单解释
7.总结
1.std::list::splice的使用
该函数是list新增的一个函数,所以需要进行额外的奖金:
splice这个函数翻译过来是:拼接、粘接的意思,也就是说可以在该list对象的position位置粘接一部分东西,但是它必须是另外一个list对象的一部分或者全部,这里是它的每个函数的用法简介:
所以说这个函数的功能还是比较多的,但是这个位置position我们需要注意:这个position我们不能直接和vector和string那样写的,所以我们如果拼接数据不是在头部或者尾部的情况下我们不能用l1.begin()+n的方式,因为这种方式是没定义的。我们可以用之前我们学过的insert的那种方式,这里讲解一下如何使用:
第一个函数的使用:
//splice函数的使用
int main()
{list<int> l1({ 4,2,4,2,1,3,5,6,0,9 });list<int> l2({ 6,3,1,8,0 });cout << "l1粘接之前:";for (const auto& e : l1){cout << e << " ";}cout << endl;cout << "l2粘接之前:";for (const auto& e : l2){cout << e << " ";}cout << endl;//(1)//不能这样写//l2.splice(l1.begin() + 1, l1);//要这样写auto i1 = std::next(l1.begin(), 1);l1.splice(i1, l2);cout << "l1第一次粘接之后:";for (const auto& e : l1){cout << e << " ";}cout << endl;cout << "l2第一次粘接之后:";for (const auto& e : l2){cout << e << " ";}cout << endl;return 0;
}
那么最终运行结果为:
但是如果我们想要插入尾结点那么就不能l1.end()了,因为
l1.end()
是指向 尾后位置(one-past-the-last element) 的迭代器,它并不指向任何实际元素。根据C++标准:
-
splice
函数的第三个参数(要剪切的元素位置)必须指向一个有效的元素 -
end()
迭代器不指向任何实际元素,因此不能用于剪切操作
所以我们如果想插入尾结点不能直接l1.end(),而应该提前一个才是:
#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
//splice函数的使用2
int main()
{list<int> l1({ 4,2,4,2,1,3,5,6,0,9 });list<int> l2({ 6,3,1,8,0 });cout << "l1粘接之前:";for (const auto& e : l1){cout << e << " ";}cout << endl;cout << "l2粘接之前:";for (const auto& e : l2){cout << e << " ";}cout << endl;//(2)//或者auto i2 = l2.begin();//l2的第四个位置粘接std::advance(i2, 3);//错误//l2.splice(i2, l1, l1.end());//正确l2.splice(i2, l1, std::prev(l1.end()));cout << "l1第二次粘接之后:";for (const auto& e : l1){cout << e << " ";}cout << endl;cout << "l2第二次粘接之后:";for (const auto& e : l2){cout << e << " ";}cout << endl;return 0;
}
那么最终运行结果为:
第三个函数的用法如下:
//splice函数的使用3
int main()
{list<int> l1({ 4,2,4,2,1,3,5,6,0,9 });list<int> l2({ 6,3,1,8,0 });cout << "l1粘接之前:";for (const auto& e : l1){cout << e << " ";}cout << endl;cout << "l2粘接之前:";for (const auto& e : l2){cout << e << " ";}cout << endl;//(3)//也可以auto i3 = l2.begin();//在l2的第四个位置开始粘接std::advance(i3, 3);l2.splice(i3, l1, l1.begin(), l1.end());cout << "l1第三次粘接之后:";for (const auto& e : l1){cout << e << " ";}cout << endl;cout << "l2第三次粘接之后:";for (const auto& e : l2){cout << e << " ";}cout << endl;return 0;
}
那么最终运行结果如下:
为什么这次没报错,因为:
-
splice
的范围版本接受的是 [first, last) 半开区间 -
标准明确规定
last
可以是end()
迭代器 -
这表示"从 first 开始到容器末尾的所有元素"
而且基本上迭代器的last指针通常是不插入这个位置的数据的(可能没有数据)。
可以看到:splice函数看似简单,但是我们需要注意的地方还是比较多的,我们还是要注意它的用法,否则很容易报错,而且我们在写i1、i2的时候我们要注意如果i1指向l1的结点,那么就是l1.splice(i1,……),不然可能会报错(自己粘接自己),如果是粘接一段迭代器区间,那么可以自己粘接自己!
2.std::list::remove和std::list::remove_if的使用
这个函数也是在list容器中新增的一个函数,所以需要额外介绍一下它用法,我们来看一下它的用法:
也就是说它可以删除值为val的所有结点,在该函数的介绍中也能了解它的很多东西,所以这里就不做解释了。
这个函数我们又有些看不懂了,如果按照正常思维,我们也应该是满足值为val且满足pred的条件就可以了,为什么这个是模板?我们来看一下它的介绍:
这个函数我们还是没看懂它如何用的,那我们还是问一下deepseek吧!(以下是deepseek的生成结果,如果不想看的话可以跳到2.2)
2.1remove_if函数的简单介绍
std::list::remove_if
是 C++ STL 中 list 容器的一个成员函数,用于根据特定条件移除列表中的元素。
基本用法
#include <list>
#include <iostream>int main() {std::list<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};// 移除所有偶数numbers.remove_if([](int n) { return n % 2 == 0; });// 输出结果: 1 3 5 7 9for (int n : numbers) {std::cout << n << " ";}return 0;
}
函数原型
template <class Predicate>
void remove_if(Predicate pred);
-
red
: 一元谓词(接受一个元素作为参数并返回 bool 的函数或函数对象) -
返回类型: void(直接修改原列表)
使用函数对象作为谓词
struct IsGreaterThan {int value;IsGreaterThan(int v) : value(v) {}bool operator()(int n) const { return n > value; }
};int main() {std::list<int> numbers = {5, 12, 3, 8, 15, 7};// 移除所有大于10的元素numbers.remove_if(IsGreaterThan(10));// 输出结果: 5 3 8 7for (int n : numbers) {std::cout << n << " ";}return 0;
}
使用普通函数作为谓词
bool isNegative(int n) {return n < 0;
}int main() {std::list<int> numbers = {-2, -1, 0, 1, 2, -3};// 移除所有负数numbers.remove_if(isNegative);// 输出结果: 0 1 2for (int n : numbers) {std::cout << n << " ";}return 0;
}
注意事项
-
remove_if
会遍历整个列表,时间复杂度为 O(n) -
被移除的元素会被销毁,内存被释放
-
与
std::remove_if
算法不同,list 的成员函数remove_if
会真正删除元素,而不只是移动元素 -
在遍历过程中修改列表是安全的,因为这是 list 的特性
复杂对象示例
#include <list>
#include <string>struct Person {std::string name;int age;
};int main() {std::list<Person> people = {{"Alice", 25},{"Bob", 17},{"Charlie", 30},{"David", 16}};// 移除所有未成年人(年龄<18)people.remove_if([](const Person& p) { return p.age < 18; });// 剩下的都是成年人for (const auto& p : people) {std::cout << p.name << " (" << p.age << ")\n";}return 0;
}
std::list::remove_if
是一个高效的方式来根据条件删除 list 中的元素,特别适合与 lambda 表达式结合使用。
2.2remove与remove_if的简单使用
在刚刚的remove_if的众多用法中我们只要掌握最基本的用法即可,建议还是传递一个返回值为bool的进去。简单来说就是remove_if能删除链表中若把链表所存储的值代入结果为true的值,所以remove_if函数在之后的用法还是比较多的,至于那个基本用法中的[]……我们暂时用这种方式即可,它是Lambda表达式,这个感兴趣的可以去搜索资料。
那么我在这里演示一下两个函数的用法,两个函数都是删除链表中的一些元素:
#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
//remove和remove_if的使用
bool isou(int a)
{return a % 2 == 0;
}
int main()
{//removelist<int> l1({ 4,2,4,6,76,3,2,1,9,0,3,5 });cout << "remove之前:";for (const auto& e : l1){cout << e << " ";}cout << endl;l1.remove(3);cout << "remove之后:";for (const auto& e : l1){cout << e << " ";}cout << endl;//remove_iflist<int> l2({ 2,4,6,3,1,7,9,0,8,5,7 });cout << "remove_if之前:";for (const auto& e : l2){cout << e << " ";}cout << endl;l2.remove_if(isou);cout << "remove_if之后:";for (const auto& e : l2){cout << e << " ";}cout << endl;return 0;
}
那么最终运行结果为:
3.std::list::unique的使用
unique也是在string和vector之后新增的一个函数,我们可以通过它函数名的意思知道这个函数大概是什么意思,这个函数的意思是单独的,那么来看一下它的介绍吧:
也就是说它可以删除连续的重复的元素,然后使每个结点与它的前后结点(除只有一个结点外)所存的值都不相同,这个函数也经常结合sort函数即排序后使用,所以这是第一个函数的用法;第二个函数和remove_if差不多,但是也有些不同,以下是deepseek的搜索结果:
3.1std::list::unique的第二个函数的简单介绍
std::list::unique
的带谓词版本允许你自定义判断相邻元素是否"唯一"的标准,而不仅仅是简单的相等比较。
基本语法
template <class BinaryPredicate>
void unique(BinaryPredicate binary_pred);
-
binary_pred
:一个二元谓词(接受两个元素作为参数并返回 bool 的函数或函数对象) -
功能:移除所有满足
binary_pred
的连续重复元素
基本示例
#include <list>
#include <iostream>int main() {std::list<int> numbers = {1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 7};// 使用默认比较(operator==)numbers.unique();// 结果:1, 2, 3, 4, 5, 6, 7// 使用自定义谓词 - 当两数差的绝对值小于等于1时视为相同numbers = {1, 2, 4, 5, 7, 8, 10};numbers.unique([](int a, int b) { return std::abs(a - b) <= 1; });// 结果:1, 4, 7, 10return 0;
}
使用函数对象作为谓词
struct AreConsecutive {bool operator()(int a, int b) const {return b == a + 1;}
};int main() {std::list<int> nums = {1, 2, 4, 5, 7, 8, 10};nums.unique(AreConsecutive());// 移除后一个元素是前一个元素+1的相邻元素// 结果:1, 4, 7, 10return 0;
}
处理自定义类型
struct Person {std::string name;int age;bool operator==(const Person& other) const {return name == other.name && age == other.age;}
};int main() {std::list<Person> people = {{"Alice", 25},{"Alice", 25}, // 重复{"Bob", 30},{"Bob", 31}, // 不同{"Charlie", 40},{"Charlie", 40} // 重复};// 移除姓名和年龄完全相同的连续记录people.unique();// 剩余: Alice(25), Bob(30), Bob(31), Charlie(40)// 自定义谓词 - 只比较姓名people.unique([](const Person& a, const Person& b) {return a.name == b.name;});// 剩余: Alice(25), Bob(30), Charlie(40)return 0;
}
注意事项
-
只移除连续重复项:
unique
只检查相邻元素,不相邻的重复元素不会被移除std::list<int> nums = {1, 2, 1, 2, 1}; nums.unique(); // 不会有任何变化,因为没有连续重复
-
谓词要求:谓词应该是等价关系(自反、对称、传递的)
-
排序后再使用:如果需要移除所有重复项(不仅是连续的),应先排序
std::list<int> nums = {1, 2, 1, 2, 1}; nums.sort(); nums.unique(); // 结果: 1, 2
-
性能:时间复杂度为 O(n),因为 list 的迭代器是双向的
-
与
std::unique
的区别:-
std::list::unique
是成员函数,真正删除元素 -
std::unique
是算法,只移动元素到容器末尾,不改变容器大小
-
这个带谓词的 unique
版本提供了极大的灵活性,让你可以定义什么样的元素应该被视为"重复"的。
3.2std::list::unique函数的使用
第二个重载的函数的参数与remove_if函数的不同就是:它所需要传的参数需要两个,因为这样才满足需要删除的条件是什么,才好进行删除。至于:
这个需要自己去搜索结果了,这里没办法细讲!
知道了这么多,我在这里演示一下两个函数的用法:
#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
//unique的使用
bool panduan(int a, int b)
{//判断绝对值是否小于2//小于2则认为相同return abs(a - b) < 2;
}
int main()
{list<int> a({ 4,34,5,2,2,5,2,1,9,0,6,3,9 });cout << "a开始时:";for (const auto& e : a){cout << e << " ";}cout << endl;a.unique();cout << "a第一次unique后:";for (const auto& e : a){cout << e << " ";}cout << endl;a.unique(panduan);cout << "a第二次unique后:";for (const auto& e : a){cout << e << " ";}cout << endl;return 0;
}
那么运行结果为:
4.std::list::merge的使用
该函数还是list新增的一个函数,这里我们先看一下它的介绍:
这个函数用得很少,在这里就只演示用法即可(第一个是默认排成升序的,第二个是可以排成降序的):
#define _CRT_SECURE_NO_WARNINGS 1
#include<list>
#include<iostream>
using namespace std;
//merge的使用
int main()
{list<int> l1({ 3,4,52,5,1,9,90,8,7,3 });list<int> l2({ 4,2,4,6,2,1,8,0,2,6 });//先排序l1.sort();l2.sort();//(1)//再merge//merge后仍然是有序的l1.merge(l2);for (const auto& e : l1){cout << e << " ";}cout << endl;//(2)list<int> l3({ 5,6,3,2,4,9,20,97 });//排成降序不能这样写//l3.sort();//我们想要排成降序就这样写(了解基本用法,之后会讲)greater<int> gt;//sort函数等下讲l3.sort(gt);l1.sort(gt);//第二个参数还是要加上的!l1.merge(l3, gt);for (const auto& e : l1){cout << e << " ";}cout << endl;return 0;
}
那么运行结果为:
5.std::list::sort函数以及std::sort(list)的使用
这个函数第一个是排成升序,第二个是排成降序,但是我们第二个函数的参数现阶段只要知道用这种方式即可:greater<int> gt;l1.sort(gt);但是记得gt的类型也要和l1一样。
这个函数也是专门针对list设计的swap函数,这个就是为了防止之后我们调用了算法库里面的函数,这个可以见我的string的模拟实现4的博客!
这个函数就不讲解它的用法了,我在这里只讲解为什么我们不用算法库里面的sort函数?
这个其实涉及到迭代器的继承关系,其中子类时特殊的父类,而在算法库的sort函数的参数是RandomAccessIterator,是最特殊的子类,只能传递随机迭代器。
6.C++迭代器(非常重要)
我在这里讲解的继承关系现在只是皮毛!!!因为这涉及到子父类的继承关系,这些将会在C++的继承博客中进行更详细讲解,这里我们只要在平常别乱用容器本身的迭代器与算法库里面的迭代器即可:
我们在C++官网中搜索:iterator,则会有:
这5个迭代器是以下迭代器:
我们是看不懂这个箭头的,也是很难理解的,我们只要知道这些分类即可。
所以以下是deepseek对它们比较简单的讲解:
这五个迭代器类别代表了C++中迭代器的不同能力和层级关系,它们构成了一种继承层次结构,从功能简单到功能强大依次是:
1. 输入迭代器 (input_iterator_tag)
-
能力:只读、单向
-
支持操作:
-
++
(前缀和后缀) -
*
(解引用,只能读取) -
==
/!=
比较
-
-
典型用途:从数据流中读取数据(如
istream_iterator
) -
限制:只能单次遍历,不能回退
2. 输出迭代器 (output_iterator_tag)
-
能力:只写、单向
-
支持操作:
-
++
(前缀和后缀) -
*
(解引用,只能写入)
-
-
典型用途:向数据流写入数据(如
ostream_iterator
) -
限制:不能读取,不能回退,通常只能单次遍历
3. 前向迭代器 (forward_iterator_tag)
-
能力:可读可写、单向
-
支持操作:
-
包含输入迭代器的所有功能
-
可以多次遍历同一序列
-
-
典型用途:单向链表(如
std::forward_list
的迭代器) -
特点:比输入/输出迭代器更强,支持多遍遍历
4. 双向迭代器 (bidirectional_iterator_tag)
-
能力:可读可写、双向移动
-
支持操作:
-
包含前向迭代器的所有功能
-
--
(前缀和后缀,可以回退)
-
-
典型用途:双向链表(如
std::list
的迭代器) -
特点:可以向前和向后移动
5. 随机访问迭代器 (random_access_iterator_tag)
-
能力:可读可写、随机访问
-
支持操作:
-
包含双向迭代器的所有功能
-
+
/-
整数(跳跃式移动) -
[]
下标访问 -
<
,>
,<=
,>=
比较
-
-
典型用途:数组/向量(如
std::vector
、std::array
的迭代器) -
特点:功能最强大的迭代器类型
6.每个容器所对应的迭代器以及注意事项
以下是deepseek的搜索结果:
面是C++标准库中主要容器及其对应的迭代器类别:
1. 序列容器 (Sequence Containers)
std::array
-
迭代器类别:随机访问迭代器 (
random_access_iterator_tag
) -
说明:支持所有随机访问操作,包括
+
、-
、[]
等
std::vector
-
迭代器类别:随机访问迭代器 (
random_access_iterator_tag
) -
说明:与数组类似,支持高效随机访问
std::deque
(双端队列)
-
迭代器类别:随机访问迭代器 (
random_access_iterator_tag
) -
说明:虽然内部结构比vector复杂,但仍提供随机访问能力
std::list
(双向链表)
-
迭代器类别:双向迭代器 (
bidirectional_iterator_tag
) -
说明:
-
支持
++
和--
操作 -
不支持随机访问(不能使用
+
、-
或[]
)
-
std::forward_list
(单向链表)
-
迭代器类别:前向迭代器 (
forward_iterator_tag
) -
说明:
-
只支持
++
操作 -
不支持
--
操作
-
2. 关联容器 (Associative Containers)
std::set
/std::multiset
-
迭代器类别:双向迭代器 (
bidirectional_iterator_tag
) -
说明:
-
元素已排序
-
支持双向遍历
-
std::map
/std::multimap
-
迭代器类别:双向迭代器 (
bidirectional_iterator_tag
) -
说明:
-
键值对已按键排序
-
支持双向遍历
-
3. 无序关联容器 (Unordered Associative Containers)
std::unordered_set
/std::unordered_multiset
-
迭代器类别:前向迭代器 (
forward_iterator_tag
) -
说明:
-
元素无序存储
-
只支持单向遍历
-
std::unordered_map
/std::unordered_multimap
-
迭代器类别:前向迭代器 (
forward_iterator_tag
) -
说明:
-
键值对无序存储
-
只支持单向遍历
-
4. 容器适配器 (Container Adaptors)
std::stack
和 std::queue
-
迭代器类别:不提供迭代器
-
说明:这些适配器专门设计为限制访问模式,不支持迭代
特殊迭代器
std::string
-
迭代器类别:随机访问迭代器 (
random_access_iterator_tag
) -
说明:行为与
std::vector<char>
类似
std::string_view
-
迭代器类别:随机访问迭代器 (
random_access_iterator_tag
) -
说明:提供对字符串的视图,支持随机访问
迭代器类别对算法的影响
不同算法对迭代器有不同要求:
-
需要随机访问迭代器的算法:
-
std::sort
-
std::binary_search
-
std::nth_element
-
-
需要双向迭代器的算法:
-
std::reverse
-
std::unique
(带谓词版本) -
std::list::sort
(成员函数)
-
-
只需要前向迭代器的算法:
-
std::search
-
std::adjacent_find
-
-
只需要输入迭代器的算法:
-
std::find
-
std::count
-
std::accumulate
-
7.简单解释
这个迭代器的分类对我们之后是用算法库里面的函数还是用容器的函数都有很多注意的地方,比如:我们不能用算法库的sort,因为list是双向迭代器即:bidirectional_iterator_tag。这个迭代器可以支持++、---的操作,但是不支持+、-的操作,因此若用算法库里面的可能会导致有些问题。
对于如何理解父子类的继承行为,我们可以认为:子类是特殊的父类,父类有的特征子类都有,我们若把子类认为是正方形,父类是长方形,这个就很容易理解了。
所以在用每个算法库里面的函数的时候还是要注意它的迭代器的类别:
如果有迭代器类型的参数且类型是Input_Iterator那么我们就只可读,也就是说只能传递Input类别的迭代器;同理对于参数是Output_Iterator类别的,那么就只能传递Output类别的迭代器;如果是单向迭代器,那么就能传递Input_Iterator、Output_Iterator和单向迭代器;如果是双向迭代器,那么可以传递除随机迭代器外的所有迭代器;如果参数类型是随机迭代器,那么就可以传递任意类型的迭代器!
我按照常用的容器,给出大概分类:vector、string、deque是随机迭代器;list、map、set是双向迭代器、forward_list、unodered_map、unordered_set是单向迭代器。
所以算法库里面的sort函数是不能用来进行list的排序的!所以我们要注意!
7.总结
list的重要函数的使用已经全部讲完了,那些比较运算符的重载、逆置函数、得到一个迭代器这些都不重要,就不讲解了,我们主要是要懂得每个函数所对应的用法,已经一些注意事项。这个我用deepseek的也是比较多,因为我自己学的不是很深入,如果照着笔记讲还不如不写博客,所以我觉得还是用deepseek更全面一些,也方便我之后复习用!
好了,C++list的使用就到这里了,下讲将讲解:list的底层。不过下讲内容可能需要下周去了,因为这周四天更新了这是第8篇了,身体有些吃不消了,已经赶得上我的笔记内容了。
喜欢的可以一键三连哦,下讲再见!
相关文章:
C++初阶-list的使用2
目录 1.std::list::splice的使用 2.std::list::remove和std::list::remove_if的使用 2.1remove_if函数的简单介绍 基本用法 函数原型 使用函数对象作为谓词 使用普通函数作为谓词 注意事项 复杂对象示例 2.2remove与remove_if的简单使用 3.std::list::unique的使用 …...
从单链表 list 中删除第 i 个元素--Python
从单链表 list 中删除第 i 个元素 一、问题引入二、解题步骤1.思维导图2.解题步骤 三、代码实现四、个人总结 一、问题引入 请编写程序,将 n 个整数顺次插入一个初始为空的单链表的表头。随后对任意给定的位序 i,删除链表中第 i 个结点。注意࿱…...
GraphPad Prism工作表的基本操作
《2025新书现货 GraphPad Prism图表可视化与统计数据分析(视频教学版)雍杨 康巧昆 清华大学出版社教材书籍 9787302686460 GraphPadPrism图表可视化 无规格》【摘要 书评 试读】- 京东图书 GraphPad Prism中包含5种工作表,每种工作表的基本操…...
C++初阶-list的使用1
目录 1.std::list简介 2.成员函数 2.1构造函数的使用 2.2list::operator的使用 3.迭代器 4.容量 4.1list::empty函数的使用 4.2list::size函数的使用 4.3list::max_size函数的使用 5.元素访问 6.修饰符 6.1list::assign函数的使用 6.2push_back和pop_back和push_fr…...
文献解读-病理影像多模态模型预测乳腺癌新辅助化疗的病理完全反应
期刊:Science Advances 影响因子:11.7,中科院1区Top 发表时间:2025年4月30日 概要:首都医科大学宣武医院放射科卢洁教授团队近日(2025年5月)在中科院1区top期刊《Sci Adv》(IF11.7&a…...
Docker-Mysql
查看容器的详细信息 docker inspect mysql-8.4.5 Docker 启动 local-mysql 的完整命令 docker run -d \--name local-mysql \-e MYSQL_ROOT_PASSWORDyour_root_password \-v /AllenDocker/mysql/data:/var/lib/mysql \-p 3306:3306 \--restart unless-stopped \mysql:8.4.5 验…...
鸿蒙进阶——CMakelist、GN语法简介及三方库通用移植指南
文章大纲 引言一、GN常用的内置变量二、GN常用的内置函数三、CMake 重要语法1、生成动态库2、生成静态库3、生成OBJECT 库4、重要的函数和模块4.1、add_definitions4.2、execute_process4.3、add_dependencies4.4、install4.5、FetchContent 四、GN 重要语法1、编译Target2、预…...
场景化应用实战系列六:检索问答系统
目录 景化应用实战系列六:检索问答系统 一、目标设定 二、关键知识点梳理 三、案例讲解与实战操作 1. 数据准备与预处理 2. 倒排表构建 3. 文本相似度计算 4. 检索问答系统实现 5. 系统优化与改进 一、目标设定 构建一个高效的检索问答系统,能…...
3452. 好数字之和
题目来源: LeetCode题目:3452. 好数字之和 - 力扣(LeetCode) 解题思路: 按要求判断求和即可。 解题代码: #python3 class Solution:def sumOfGoodNumbers(self, nums: List[int], k: int) -> int:r…...
GEE数据下载问题记录
GEE下载数据时的一些记录 1. GPT说 2. 验证 在未指定投影坐标系的情况下,下载原始数据导出的是MODIS Sinusoidal投影,如果单纯的对波段值进行操作,不会进行投影转换,如果涉及到波段平均,则会转投影到WGS84坐标系。如…...
P1833 樱花
P1833 樱花 - 洛谷 题目背景 《爱与愁的故事第四弹plant》第一章。 题目的描述 爱与愁大神后院里种了n棵樱花树,每棵都有美学值Ci(0≤Ci≤200)。爱与愁大神在每天上学前都会来赏花。爱与愁大神可是生物学霸,他懂得如何欣赏樱花:一种樱…...
文件操作和IO-3 文件内容的读写
文件内容的读写——数据流 流是操作系统提供的概念,Java对操作系统的流进行了封装。 数据流就像水流,生生不息,绵延不断。 水流的特点:比如要100mL的水,可以一次接10mL,分10次接完,也可以一次接…...
Day 0015:Metasploit 基础解析
目录 一、理论学习(Metasploit 架构与核心组件) 一、架构设计:分层与模块化 基础层(Ruby 框架): 核心层(模块引擎): 接口层(交互界面)&#…...
相机标定与图像处理涉及的核心坐标系
坐标系相互关系 #mermaid-svg-QxaMjIcgWVap0awV {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-QxaMjIcgWVap0awV .error-icon{fill:#552222;}#mermaid-svg-QxaMjIcgWVap0awV .error-text{fill:#552222;stroke:#552…...
单例模式的运用
单例模式实现分析 在我们的向量数据库配置类 MilvusVectorDatabaseConfig 中,采用了单例模式的实现方式,这是一种非常经典且实用的设计模式。 饿汉式单例实现 这种实现方式属于饿汉式单例模式,它的优点在于: // 在类加载时就创…...
PageHelper分页原理解析:从源码到MySQL方言实现
一、引言 分页查询是Web开发的必备功能,MyBatis生态中的PageHelper以其简单易用的特性广受欢迎。本文将从源码层面(v5.3.2)解析PageHelper的分页实现机制,结合MySQL方言展示完整的执行链路。 二、核心实现原理 1. 插件初始化 …...
MySQL中索引最左前缀法则、索引失效情况、前缀索引、索引设计原则
最左前缀法则 联合索引中,最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列,如果跳跃某一列,索引将会部分失效(后面的字段索引失效)举例假设有一个联合索引包含三个字段按顺序:…...
pdf图片导出(Visio和Origin)
一、Visio 导入pdf格式图片 1. 设计->大小,适应绘图。 2. 文件->导出,导出为pdf格式。 上面两部即可得到只包含图的部分的pdf格式。 如果出现的有默认白边,可以通过以下方式设置: 1. 文件->选项->自定义功能区->…...
NR 通讯的整体架构
前言: 并假设发射器发送了一个信号,如左下角所示(蓝色),接收器检测到的信号显示在右侧(红色)。您在图中注意到的第一件事是什么?那就是发送的信号和接收的信号并不完全相同。 有什么…...
【大模型面试每日一题】Day 26:从伦理角度,大模型可能存在哪些潜在风险?技术上如何实现内容安全控制(如RLHF、红队测试)?
【大模型面试每日一题】Day 26:从伦理角度,大模型可能存在哪些潜在风险?技术上如何实现内容安全控制(如RLHF、红队测试)? 📌 题目重现 🌟🌟 面试官:从伦理角度…...
第六届电子通讯与人工智能国际学术会议(ICECAI 2025)
在数字化浪潮中,电子通讯与人工智能的融合正悄然重塑世界的运行逻辑。技术基础的共生关系是这场变革的核心——电子通讯如同“信息高速公路”,通过5G等高速传输技术,将海量数据实时输送至AI系统,使其能够像人类神经系统般快速响应…...
深入剖析 5G 核心网中的 PLMN
一、引言 在 5G 技术迅猛发展的当下,5G 核心网作为整个通信系统的关键枢纽,支撑着海量数据传输、低延迟通信以及多样化业务应用。其中,公共陆地移动网络(Public Land Mobile Network,PLMN)扮演着极为重要的角色,它是 5G 核心网实现用户接入、网络管理以及业务提供的基础…...
佰力博科技与您探讨半导体电阻测试常用的一些方法
一、两探针法 两探针法是一种较为基础的测试方法。该方法将两根探针与半导体样品表面紧密接触,通过电源在两根探针之间施加电压,同时使用电流表测量通过样品的电流,再根据欧姆定律计算电阻。这种方法的优点在于操作简单、设备要求较低&a…...
5G 核心网中的 NPN 功能详解
引言 在 5G 技术飞速发展的今天,5G 核心网不断演进,为各类应用场景提供强大支撑。其中,NPN(Non-Public Network,非公共网络)功能作为 5G 核心网的重要特性,正逐渐崭露头角,在众多行业中发挥着关键作用。它为特定用户或组织打造专属网络环境,满足其对网络性能、安全性…...
谷歌medgemma-27b-text-it医疗大模型论文速读:多语言大型语言模型医学问答基准测试MedExpQA
《MedExpQA: 多语言大型语言模型医学问答基准测试》论文解析 一、引言 论文开篇指出大型语言模型(LLMs)在医学领域的巨大潜力,尤其是在医学问答(QA)方面。尽管LLMs在医学执照考试等场景中取得了令人瞩目的成绩&#…...
# 深入解析BERT自然语言处理框架:原理、结构与应用
深入解析BERT自然语言处理框架:原理、结构与应用 在自然语言处理(NLP)领域,BERT(Bidirectional Encoder Representations from Transformers)框架的出现无疑是一个重要的里程碑。它凭借其强大的语言表示能…...
js中encodeURIComponent函数使用场景
encodeURIComponent 是 JavaScript 中的一个内置函数,它的作用是: 将字符串编码为可以安全放入 URL 的形式。 ✅ 为什么需要它? URL 中有一些字符是有特殊意义的,比如: ? 用来开始查询参数 & 分隔多个参数 连接…...
【NLP 77、Python环境管理工具之conda】
如果你第一万次否定自己,那我希望我可以一万零一次大声称赞你 —— 25.5.22 一、什么是conda conda是一个开源的包管理系统和环境管理系统,主要用于Python语言,但也可以用于其它语言的项目 二、为什么要使用conda ① 多环境共存,多…...
替代云数据库的本地方案:MySQL+phpMyAdmin的远程管理与跨网络访问技术
文章目录 前言1. 安装MySQL2. 安装phpMyAdmin3. 修改User表4. 本地测试连接MySQL5. 安装cpolar内网穿透6. 配置MySQL公网访问地址7. 配置MySQL固定公网地址8. 配置phpMyAdmin公网地址9. 配置phpmyadmin固定公网地址 前言 对于运维来说,平时还好,一旦出门…...
Dify大语言模型应用开发环境搭建:打造个性化本地LLM应用开发工作台
文章目录 前言1. Docker部署Dify2. 本地访问Dify3. Ubuntu安装Cpolar4. 配置公网地址5. 远程访问6. 固定Cpolar公网地址7. 固定地址访问 前言 各位小伙伴们,大家好!今天我们要来一场技术大冒险,手把手教你如何在Linux Ubuntu系统上使用Docke…...
MySQL索引事务
索引 通过索引可以对查询操作进行优化,通过减少全表扫描,快速定位数据,原本的查询操作是对表进行遍历,如果是大表效率较低 1)注意事项 占用了更多的空间,由于生成索引需要依赖于数据结构和额外数据&…...
Seay代码审计工具
Seay代码审计工具 介绍 Seay代码审计工具是一款由国内安全研究人员"Seay"开发的源代码安全审计工具,主要用于帮助安全人员快速发现PHP代码中的安全漏洞,快速定位代码中的安全风险点。 主要功能特点 自动化审计功能 支持自动扫描PHP代码中的…...
【人工智障生成日记1】从零开始训练本地小语言模型
🎯 从零开始训练本地小语言模型:MiniGPT TinyStories(4090Ti) 🧭 项目背景 本项目旨在以学习为目的,从头构建一个完整的本地语言模型训练管线。目标是: ✅ 不依赖外部云计算✅ 完全本地运行…...
技术分享:大数据挖掘平台架构设计与行业应用实践
在数字化转型浪潮下,企业数据规模呈指数级增长。如何构建高效的数据挖掘体系,实现数据价值变现,成为技术团队面临的重要课题。本文将深入探讨大数据挖掘平台的核心架构、关键技术及行业应用实践。 一、平台架构设计 1. 数据采集层 支持多源异…...
线性Wi-Fi FEM被卷死,非线性FEM是未来?
在跑了一圈路由器客户之后,我的内心反而平静下来,被卷死的不只是Wi-Fi FEM赛道,还有家用路由器市场。 尽管路由器市场比较惨淡,不过客户还是很愿意接见我,并做更广泛的交流和探讨。一方面之前推Wi-Fi FEM的众多厂商在渐…...
OpenCV CUDA模块图像过滤------用于创建一个最小值盒式滤波器(Minimum Box Filter)函数createBoxMinFilter()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 该函数创建的是一个 最小值滤波器(Minimum Filter),它对图像中每个像素邻域内的像素值取最小值。常用于&…...
【MySQL】06.MySQL表的增删查改
1. insert 我们先创建一个表结构,这部分操作我们使用这张表完成我们的操作: mysql> create table student(-> id int primary key auto_increment,-> name varchar(20) not null,-> qq varchar(20) unique-> ); Query OK, 0 rows affec…...
MySQL 索引失效及其解决办法
一、前言 在数据库优化中,索引(Index)是一项至关重要的技术手段,可以显著提升查询性能。然而,在实际开发过程中,MySQL 索引并不总是如预期生效。本文将从原理出发,系统地介绍索引失效的常见场景及其解决方案,帮助开发者有效规避性能陷阱。 二、索引基础回顾 MySQL 支…...
在线时间戳(Unix TimeStamp)转换器
做了一个在线时间戳转换器,简单、好用,提供多种日期格式。 移动端友好。 目标是做一套在线工具集,时间戳转换只是第一步。 欢迎试用...
flutter 项目调试、flutter run --debug调试模式 devtools界面说明
Flutter DevTools 网页界面说明 1. 顶部导航栏 Inspector:查看和调试 Widget 树,实时定位 UI 问题。Performance-- 性能分析面板,查看帧率、CPU 和 GPU 使用情况,识别卡顿和性能瓶颈。Memory-- 内存使用和对象分配分析ÿ…...
Qt C++实现马的遍历问题
在这个项目中,我们面对的是一个基于中国象棋的马的遍历问题,使用了C++编程语言,并结合了Qt5库来实现图形界面和棋盘的绘制。以下是这个项目涉及的关键知识点: 马的移动规则:马在象棋中具有独特的“日”字形移动方式,即每次可以向前、后、左或右移动一格,然后在同一行或同…...
web第六次课后作业--使用ApiFox实现请求响应操作
一、实体参数 1.1 简单实体参数 1.2 复杂实体对象 如果请求参数比较多,通过上述的方式一个参数一个参数的接收会比较繁琐。此时,我们可以考虑将请求参数封装到一个实体类对象中。 要想完成数据封装,需要遵守如下规则:请求参数名…...
第十周作业
一、CSRF 1、DVWA-High等级 2、使用Burp生成CSRF利用POC并实现攻击 二、SSRF:file_get_content实验,要求获取ssrf.php的源码 三、RCE 1、 ThinkPHP 2、 Weblogic 3、Shiro...
Excel合并单元格后,如何自动批量生成序号列
1.选择整列 2.组合键:CtrlG 3.定位条件,选择“空值” 4.在第一个框中输入“MAX(”,鼠标选中A1框,后加“:”,鼠标选中前方“A1”,按“F4”绝对引用,补全右括号,后输入“1…...
数据结构 -- B树和B+树
B树 B树 5叉查找树 最少1个关键字,2个分叉 最多4个关键字,5个分叉 如何保证查找效率 (1)eg.对于5叉排序树,规定除了根节点外,任意结点都至少有3个分叉,2个关键字 (若每个结点内关…...
el-table高度自适应、数据查询后高度展示错误问题
在很多场景中我们需要实现表格的高度自适应,即不同屏幕大小下需要使用不同的高度来设置表格,那么我们应该如何实现呢? 1.el-table实现高度自适应 通过以下代码可以实现表格根据屏幕进行自适应 设置表格的高度 <el-table ref"tableD…...
unittest
1.什么是unittest? unittest是Python自带的一个单元测试框架, 它可以做单元测试, 也能用于编写和运行重复的测试工作。它给自动化测试用例开发和执行提供了丰富的断言方法, 判断测试用例是否通过, 并最终生成测试结果. 2.unittest组成 2.1 TestCase TestCase即测试…...
【Linux学习笔记】ext2文件系统的深度剖析
【Linux学习笔记】ext2文件系统的深度剖析 🔥个人主页:大白的编程日记 🔥专栏:Linux学习笔记 文章目录 【Linux学习笔记】ext2文件系统的深度剖析前言一.ext2文件系统1.1宏观认识 二. Block Group三. 块组内部构成3.1 超级块&am…...
Vue 3 官方 Hooks 的用法与实现原理
Vue 3 引入了 Composition API,使得生命周期钩子(hooks)在函数式风格中更清晰地表达。本篇文章将从官方 hooks 的使用、实现原理以及自定义 hooks 的结构化思路出发,全面理解 Vue 3 的 hooks 系统。 📘 1. Vue 3 官方生…...
通过现代数学语言重构《道德经》核心概念体系,形成一个兼具形式化与启发性的理论框架
以下是对《道德经》的数学转述尝试,通过现代数学语言重构其核心概念,形成一个兼具形式化与启发性的理论框架: 0. 基础公理体系 定义: 《道德经》是一个动态宇宙模型 U(D,V,Φ),其中: D 为“道”的无限维…...