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

C++STL——map和set的使用

目录

1.容器

1.1 序列容器

1.2 容器适配器

1.3 关联容器

1.4 无序关联容器

1.5 键值对到底是个什么东西?

2.set系列的使用

2.1 set类的介绍

2.2 set的构造以及迭代器

2.3 set的增,删,查

2.3.1 插入

2.3.2 删除

2.3.3 查找

2.3.4 lower_bound 以及 upper_bound

2.4 multiset与set的差异

3.map系列的使用

3.1 map类的介绍

3.2 pair类型的介绍

3.3 map的构造

3.3 map的增,删,查

3.4 map数据的修改

3.5 multimap与map的差异


1.容器

在C++标准库中,容器是用于存储和管理数据集合的模板类,根据数据组织方式和功能特性,它们可以分为以下几类:

1.1 序列容器

就是按照线性顺序存储元素,元素的顺序由插入顺序决定。常用的容器就是以上那几个,咱们应该多少都讲过。这里前三个都是随机迭代器,迭代器支持的功能最多,第四个是单向迭代器,迭代器支持的功能最少,第五个是双向迭代器,位于单向迭代器与随机迭代器的中间位置。 

特点:vector:动态数组,支持快速随机访问(O(1));尾部插入/删除高效(O(1)),但是中间插入/删除较慢(O(n))。

list:双向链表,任意位置插入/删除高效(O(1)),但随机访问慢(O(n))

deque:双端队列,支持头尾高效插入/删除(O(1)),随机访问较快(O(1))

array:固定大小的数组,编译时确定大小,无法动态扩容

forward_list:单向链表,内存占用更小,但仅支持单向遍历

所以说如果要频繁的在中间插入或者删除,就用list或者forward_list。需要随机访问就用vector或者deque。只能说没有完全好的容器,各有各的好处。

1.2 容器适配器

基于其他容器实现的接口,提供特定数据结构的抽象(如栈,队列)。

特点:stack:后进先出,底层是基于deque实现

queue:先进先出,底层基于deque实现

priority_queue:元素按优先级排序,默认基于vector实现堆结构。

并且容器适配器是没有迭代器的。

1.3 关联容器

这个是咱们今天要讲的重点 

 基于键(key)有序存储元素,通常用红黑树实现,支持高效的查找。这个可以理解为,有关联的容器。

特点:set:唯一键集合,元素即键

map:键值对集合,键唯一

multiset/multimap:允许重复键(允许冗余)

并且他们的迭代器都是双向迭代器。

1.4 无序关联容器

这个是基于哈希表实现的,元素无序但是查找更快(平均O(1)),这个毕竟还没学,暂时不讲。

1.5 键值对到底是个什么东西?

那么既然讲到键值对了,就来说一下,键值对是个什么东西? 

在C++的std::map中,key(键)和value(值)是键值对(Key-Value Pair)的两个核心组成部分,它们共同构成了一种关联关系,这也是为什么叫它关联容器。

key(键):

定义:用于唯一标识元素的“标识符”,类似于词典中的“词条”。

特点:

唯一性:在map中,所有的key必须唯一(若需要允许重复的键,需用std:multimap)。

不可变性:key一旦插入到map中,就不能直接修改,(但可以删除后重新插入)

排序性:map默认按key的升序排序(可通过仿函数修改)

value(值):

定义:与key关联的数据,类似于字典中词条对应的“解释”。

特点:1.相同的key可以对应不同的value

2.可以通过key直接修改value的值。

那么来看他们的实际应用场景:

1.字典/数据库索引:

key:单词(如apple)

value:单词的释义(如一种水果)

2.学生信息管理系统

key:学号(唯一标识学生,如“s001”)

value:学生详细信息(如Alice,18,CS).

这也是对上一章最后的补充。OK,让咱们进入主题吧

本章节讲解的map和set底层是红黑树,红黑树是⼀颗平衡二叉搜索树。set是key搜索场景的结构, map是key/value搜索场景的结构。

2.set系列的使用

2.1 set类的介绍

set的声明如下,T就是set底层关键字的类型

• set默认要求T支持小于比较,如果不支持或者想按自己的需求走可以自行实现仿函数传给第二个模 版参数

• set底层存储数据的内存是从空间配置器申请的,如果需要可以自己实现内存池,传给第三个参 数。

• ⼀般情况下,我们都不需要传后两个模版参数。

• set底层是用红黑树实现,增删查效率是 的。 

前⾯部分我们已经学习了vector/list等容器的使用,STL容器接口设计,高度相似,在这里我只挑选几个比较重要的接口来将。

2.2 set的构造以及迭代器

大家只需要知道这四个构造即可:无参默认构造, 迭代器区间构造,拷贝构造,列表构造。

 迭代器是⼀个双向迭代器:-> a bidirectional iterator to const value_type

正向迭代器  iterator begin(); iterator end();

 反向迭代器 reverse_iterator rbegin(); reverse_iterator rend();

set的支持正向和反向迭代遍历,遍历默认按升序顺序,因为底层是二叉搜索树,迭代器遍历走的中 序;支持迭代器就意味着支持范围for,set的iterator和const_iterator都不支持迭代器修改数据,修改 关键字数据,破坏了底层搜索树的结构。

2.3 set的增,删,查

需要说明的是key_type与value_type均为T,即key。 

2.3.1 插入

1.单个数据插入,如果已经存在则插入失败 pair <iterator,bool>insert (const value_type& val);

2. 列表插入,已经在容器中存在的值不会插入 void insert (initializer_list<value_type> il);

 3.迭代器区间插入,已经在容器中存在的值不会插⼊ template <Class InputIterator>

void insert (InputIterator first, InputIterator last);

来看一段测试代码:

int main()
{// 去重+升序排序set<int> s;// 去重+降序排序(给一个大于的仿函数)//set<int, greater<int>> s;s.insert(5);s.insert(2);s.insert(7);s.insert(5);//set<int>::iterator it = s.begin();auto it = s.begin();while (it != s.end()){// error C3892: “it”: 不能给常量赋值// *it = 1;cout << *it << " ";++it;}cout << endl;// 插入一段initializer_list列表值,已经存在的值插入失败s.insert({ 2,8,3,9 });for (auto e : s){cout << e << " ";}cout << endl;set<string> strset = { "sort", "insert", "add" };// 遍历string比较ascll码大小顺序遍历的for (auto& e : strset){cout << e << " ";}cout << endl;return 0;
}

 

上面的为运行结果。

注意插入单个元素返回的是pair,pair是一个自定义类型,第一个成员是iterator,第二个成员是bool,第一个元素是指向插入元素的迭代器,第二个表示是否插入成功。如果插入成功,iterator指向插入的元素,bool为true。如果元素已存在,iterator指向已经存在的元素,bool为false。

2.3.2 删除

  1.删除⼀个迭代器位置的值 iterator erase (const_iterator position);

2. 删除 val , val 不存在返回 0 ,存在返回 1 size_type erase (const value_type& val);

 3.删除⼀段迭代器区间的值 iterator erase (const_iterator first, const_iterator last);

这儿为什么不用bool判断是否删除成功了呢?其实也是因为后面会讲到multiset,所以这儿先知道一下,后面会讲。且这儿只能返回0或1,因为set是去重过的。

set<int> s = { 4,2,7,2,8,5,9 };
for (auto e : s)
{cout << e << " ";
}
cout << endl;s.erase(s.begin());for (auto e : s)
{cout << e << " ";
}
cout << endl;// 直接删除x
int x;
cin >> x;
int num = s.erase(x);
if (num == 0)
{cout << x << "不存在!" << endl;
}for (auto e : s)
{cout << e << " ";
}
cout << endl;// 直接查找再利用迭代器删除x
int x;
cin >> x;
auto pos = s.find(x);
if (pos != s.end())
{s.erase(pos);
}
else
{cout << x << "不存在!" << endl;
}for (auto e : s)
{cout << e << " ";
}
cout << endl;

删除对应的代码。

2.3.3 查找

find找到了返回当前元素的迭代器,否则返回end位置的迭代器。

1. 查找 val ,返回 val 所在的迭代器,没有找到返回 end() iterator find (const value_type& val);

 2.查找 val ,返回 Val 的个数 size_type count (const value_type& val) const; 

还有一种查找,即count,返回的是key的个数有几个,就返回几个,但是set中只有0或1个,而后面讲的multiset会有多个。

// O(N)
auto pos1 = find(s.begin(), s.end(), x);
// O(logN)
auto pos2 = s.find(x);cin >> x;
/*auto pos = s.find(x);
if (pos != s.end())*/
if(s.count(x))
{cout << x << "存在!" << endl;
}
else
{cout << x << "不存在!" << endl;
}

这儿的find如果是算法库中的find,那么其实本质是暴力查找,时间复杂度为O(N),是为了vector准备的,其实远不如使用自带的find成员函数。

2.3.4 lower_bound 以及 upper_bound

1.返回大于等 val 位置的迭代器 iterator lower_bound (const value_type& val) const;

有这个值,就返回val位置的iterator。无这个值,就返回比val大的位置的iterator。

2.返回大于 val 位置的迭代器 iterator upper_bound (const value_type& val) const; 

有这个值,就返回比val值大的位置的iterator。无val这个值,也返回大于val值的迭代器的位置。

咱们知道迭代器的区间都是左闭右开的,那么这个就是为了寻找迭代器的区间而存在的。

lower_bound是为了找闭区间,而另一个是为了找开区间。

int main()
{std::set<int> myset;for (int i = 1; i < 10; i++)myset.insert(i * 10); // 10 20 30 40 50 60 70 80 90for (auto e : myset){cout << e << " ";}cout << endl;/* 实现查找到的[itlow,itup)包含[30, 60]区间返回 >= 30*/auto itlow = myset.lower_bound(30);// 返回 > 60auto itup = myset.upper_bound(60);myset.erase(itlow, itup);for (auto e : myset){cout << e << " ";}cout << endl;// 实现查找到的[itlow,itup)包含[35, 65]区间// 返回 >= 35auto itlow = myset.lower_bound(35);// 返回 > 65auto itup = myset.upper_bound(65);myset.erase(itlow, itup);for (auto e : myset){cout << e << " ";}cout << endl;// 实现查找到的[itlow,itup)包含[30, 90]区间auto itlow = myset.lower_bound(30);auto itup = myset.upper_bound(90);myset.erase(itlow, itup);for (auto e : myset){cout << e << " ";}cout << endl;return 0;
}

以上是一段删除代码,请大家仔细观摩。

2.4 multiset与set的差异

multiset和set的使⽤基本完全类似,主要区别点在于multiset支持值冗余,那么 insert/find/count/erase都围绕着支持值冗余有所差异,具体参看下⾯的样例代码理解。 

int main()
{// 相比set不同的是,multiset是排序,但是不去重multiset<int> s = { 4,2,7,2,4,8,4,5,4,9 };auto it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;// find返回中序的第一个4auto pos = s.find(4);while (*pos == 4){cout << *pos << " ";++pos;}cout << endl;cout << s.count(4) << endl;cout << s.count(5) << endl;cout << s.count(6) << endl;//若是erase参数只给一个要删除的数字,那么会删除所有的这个数字,且返回删除的数字的个数// 若是erase的参数是迭代器,那么只会删除该位置的数字// 删除所有的4//cout << s.erase(4) << endl;// 删除中序第一个4pos = s.find(4);if(pos != s.end())s.erase(pos);it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;return 0;
}

 

所以这里知道为什么erase的返回值要是size_type的了吧,就是为了与multiset区分开。那么这儿的count自然也是发挥了很大的作用。 

3.map系列的使用

3.1 map类的介绍

map的声明如下,Key就是map底层关键字的类型,T是map底层value的类型,set默认要求Key支持 小于比较,如果不支持或者需要的话可以自行实现仿函数传给第二个模版参数,map底层存储数据的 内存是从空间配置器申请的。⼀般情况下,我们都不需要传后两个模版参数。map底层是⽤红黑树实 现,增删查改效率是 O(logN) ,迭代器遍历是走的中序,所以是按key有序顺序遍历的。

那么我们来思考一个东西,在set中,只有一个key,所以你要是想访问数据,直接就可以访问了,但是对于key_value的呢?一个里面有两个值啊,好,那么这个之后,咱们可以用pair去存储,你可以把pair理解为一个结构体。两个成员,即key,value即为结构体的成员变量。咱们访问的时候,直接访问结构体中的成员变量即可。

3.2 pair类型的介绍

map底层的红黑树节点中的数据,使用pair<Key,T>存储键值对数据。

 

3.3 map的构造

也是只需要掌握4个即可:无参数构造,迭代器区间构造,拷贝构造,参数列表构造。

迭代器是⼀个双向迭代器 iterator -> a bidirectional iterator to const value_type

 正向迭代器 iterator begin(); iterator end();

 反向迭代器 reverse_iterator rbegin(); reverse_iterator rend(); 

map的支持正向和反向迭代遍历,遍历默认按key的升序顺序,因为底层是二叉搜索树,迭代器遍历走 的中序;支持迭代器就意味着支持范围for,map支持修改value数据,不支持修改key数据,修改关键 字数据,破坏了底层搜索树的结构。

3.3 map的增,删,查

这儿的key就是key,这儿的T其实就是value,这儿的pair<Key,Value>其实就是value_type。

map的增删查关注以下几个接⼝即可: map增接口,插⼊的pair键值对数据,跟set所有不同,但是查和删的接口只用关键字key跟set是完全 类似的,不过find返回iterator,不仅仅可以确认key在不在,还找到key映射的value,同时通过迭代 还可以修改value 。

int main()
{map<string, string> dict;pair<string, string> kv1("sort", "排序");dict.insert(kv1);dict.insert(pair<string, string>("left", "左边"));dict.insert(make_pair("left", "左边"));dict.insert({ "right", "右边" });//map<string, string>::iterator it = dict.begin();auto it = dict.begin();while (it != dict.end()){//因为咱们知道,*的返回值是引用类型,所以可以直接用.访问结构体里的成员// 但是,->的返回值是&(取地址),指针类型,所以,这儿其实是it->->first,// 为了可读性,就省去一个->。//cout << (*it).first <<":" << (*it).second <<endl;//(*it).second = "左边1";说明map中的value是可以修改的cout << it->first << ":" << it->second << endl;++it;}cout << endl;for (auto& e : dict){cout << e.first << ":" << e.second << endl;}cout << endl;string str;while (cin >> str){auto ret = dict.find(str);if (ret != dict.end()){cout << "->" << ret->second << endl;}else{cout << "无此单词,请重新输入" << endl;}}return 0;
}

大家有什么疑问,请看上面的代码。

 

插入,不管什么,都是插入成功。删除的接口与set的删除接口一样的,就不演示了。

即erase传Key,会将Key对应的Value全删了,count的返回值为Key的Value有几个,就返回几。

3.4 map数据的修改

咱们先来看一段代码:

int main()
{string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜","苹果", "香蕉", "苹果", "香蕉" };map<string, int> countMap;for (auto& str : arr){/*auto pos = countMap.find(str);if (pos != countMap.end()){pos->second++;}else{countMap.insert({ str, 1 });}*///以上的代码可以等价于下面的一个代码countMap[str]++;}for (auto& e : countMap){cout << e.first << ":" << e.second << endl;}cout << endl;return 0;
}

OK,咱们来讲解一下这个[],

这个【】,返回值是Value,而方括号里面写的是Key。

这个【】,也可以用来访问Key中的Value,以及修改Value,但是上面代码有点问题,就是对于已有的数据,直接++没问题,但是对于没有的数据怎么办呢?其实,【】会先插入Key,之后Value为second的默认构造(一般往0那边去靠),这儿int的默认构造是0.所以会先插入Key,之后0+1=1. 

int main()
{map<string, string> dict;dict.insert({ "sort", "排序" });// 增加dict["left"] = "左边";// 增加dict["right"]="右边";// 修改dict["right"] = "右边1";// 查找,你得确定值在其中,否则就变成插入了cout << dict["left"] << endl;cout << dict["kkk"] << endl;//不可以,因为map是去重的dict.insert({ "sort", "xxxx" });for (auto& e : dict){cout << e.first << e.second << endl;}return 0;
}

 

以上就是方括号的用法。 

那么方括号的底层呢,其实是运用了insert。

需要注意的是这个ret.first,指的是访问的是指向节点的指针。第二个->访问的才是节点里面的成员变量。

insert 插⼊⼀个 pair 对象

 1 、如果 key 已经在 map 中,插⼊失败,则返回⼀个 pair 对象,返回 pair 对象 first 是 key 所在结点的迭代器, second 是 false

 2 、如果 key 不在在 map 中,插入成功,则返回⼀个 pair 对象,返回 pair 对象 first 是新插⼊ key 所在结点的迭代器, second 是 true

3.也就是说无论插入成功还是失败,返回 pair 对象的 first 都会指向 key 所在的迭 代器

4. 那么也就意味着 insert 插入失败时充当了查找的功能,正是因为这⼀点, insert 可以用来实现 operator[]

5. 需要注意的是这里有两个 pair ,不要混淆了,⼀个是 map 底层红黑树节点中存的 pair ,另 ⼀个是 insert 返回值 pair  。

3.5 multimap与map的差异

multimap和map的使用基本完全类似,主要区别点在于multimap支持关键值key冗余,那么 insert/find/count/erase都围绕着支持关键值key冗余有所差异,这里跟set和multiset完全⼀样,比如 find时,有多个key,返回中序第⼀个。其次就是multimap不支持[],因为支持key冗余,[]就只能支持插入了,不能支持修改。

OK,本篇只讲了map与set系列的使用,还有一点就是map与multimap包的是同一个头文件。set与multiset也是的。

 

 

 

相关文章:

C++STL——map和set的使用

目录 1.容器 1.1 序列容器 1.2 容器适配器 1.3 关联容器 1.4 无序关联容器 1.5 键值对到底是个什么东西&#xff1f; 2.set系列的使用 2.1 set类的介绍 2.2 set的构造以及迭代器 2.3 set的增&#xff0c;删&#xff0c;查 2.3.1 插入 2.3.2 删除 2.3.3 查找 2.3.4…...

Ensemble Alignment Subspace Adaptation Method for Cross-Scene Classification

用于跨场景分类的集成对齐子空间自适应方法 摘要&#xff1a;本文提出了一种用于跨场景分类的集成对齐子空间自适应&#xff08;EASA&#xff09;方法&#xff0c;它可以解决同谱异物和异谱同物的问题。该算法将集成学习的思想与域自适应&#xff08;DA&#xff09;算法相结合…...

AFFS2 的 `yaffs_ext_tags` 数据结构详解

YAFFS2 的 yaffs_ext_tags 数据结构详解 yaffs_ext_tags 是 YAFFS2 文件系统中用于 管理 NAND 闪存页的元数据 的核心结构体&#xff0c;存储在 NAND 的 OOB&#xff08;Out-Of-Band&#xff09;区域。它记录了数据块的归属、状态、校验信息等关键元数据&#xff0c;是 YAFFS2…...

CSS经典布局之圣杯布局和双飞翼布局

目标&#xff1a; 中间自适应&#xff0c;两边定宽&#xff0c;并且三栏布局在一行展示。 圣杯布局 实现方法&#xff1a; 通过float搭建布局margin使三列布局到一行上relative相对定位调整位置&#xff1b; 给外部容器添加padding&#xff0c;通过相对定位调整左右两列的…...

超声波传感器模块

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 1.HC-SR04介绍2.HC-SR04原理介绍2.1原理概述3.2原理详解 4驱动代码编写4.1写前思考4.2硬件连线 5.总结hcsr04.hhcsr04.c 1.HC-SR04介绍 超声波传感器有很多种类的型号&#xff1a;HC-SR04、UC-025、…...

使用scp命令拷贝hadoop100中文件到其他虚拟机中

以下是使用 scp 命令将 hadoop100 主机中的文件拷贝到其他虚拟机的操作步骤&#xff08;假设其他主机名为 hadoop101 、 hadoop102 &#xff0c;系统为 Linux&#xff09;&#xff1a; 1. 基本语法 bash scp [选项] 源文件路径 目标主机用户名目标主机IP:目标路径 - 选…...

Linux基础 -- 用户态Generic Netlink库高性能接收与回调框架

用户态Generic Netlink库高性能接收与回调框架 一、概述 在 Linux 系统中&#xff0c;Netlink 是用户态与内核态通信的强大机制。libnl 是一个专为简化 Netlink 编程而设计的库&#xff0c;提供了接收和处理 Netlink 消息的高级接口。libnl-genl 是其通用 Netlink (Generic N…...

java中的Optional

在 Java 8 中&#xff0c;Optional 是一个用于处理可能为 null 的值的容器类&#xff0c;旨在减少空指针异常&#xff08;NullPointerException&#xff09;并提升代码的可读性。以下是 Optional 的核心用法和最佳实践&#xff1a; 1. 创建 Optional 对象 1.1 常规创建方式 Op…...

原型和原型链

原型&#xff08;Prototype&#xff09; 和 原型链&#xff08;Prototype Chain&#xff09; 是 JavaScript 中非常重要的概念&#xff0c;它们是 JavaScript 实现继承和共享属性和方法的核心机制。理解原型和原型链可以帮助你更好地掌握 JavaScript 的面向对象编程&#xff08…...

解锁Python TDD:从理论到实战的高效编程之道(9/10)

引言 在 Python 开发的广袤天地中&#xff0c;确保代码质量与稳定性是每位开发者的核心追求。测试驱动开发&#xff08;TDD&#xff0c;Test-Driven Development&#xff09;作为一种强大的开发理念与实践方法&#xff0c;正逐渐成为 Python 开发者不可或缺的工具。TDD 强调在…...

OpenMCU(七):STM32F103开发环境搭建

概述 本文主要讲述了使用Keil软件搭建STM32F103嵌入式开发环境的步骤&#xff0c;主要面向想从事嵌入式行业的入门同学&#xff0c;如果下面的讲述过程中有不对的地方&#xff0c;欢迎大家给我留言。 本文主要讲述了Keil 5.43的安装教程&#xff0c;主要用于学习交流&#xf…...

六、Hive 分桶

作者&#xff1a;IvanCodes 日期&#xff1a;2025年5月13日 专栏&#xff1a;Hive教程 在 Hive 中&#xff0c;除了常见的分区&#xff08;Partitioning&#xff09;&#xff0c;分桶&#xff08;Bucketing&#xff09;是另一种重要且有效的数据组织和性能优化手段。它允许我们…...

INFINI Console 纳管 Elasticsearch 9(一):指标监控、数据管理、DSL 语句执行

Elasticsearch v9.0 版本最近已发布&#xff0c;而 INFINI Console 作为一款开源的非常轻量级的多集群、跨版本的搜索基础设施统一管控平台&#xff0c;是否支持最新的 Elasticsearch v9.0 集群管理呢&#xff1f;本文以 INFINI Console v1.29.2 为例&#xff0c;从指标监控、数…...

ansible进阶版01

ansible进阶版01 欢迎使用Markdown编辑器最佳实践保持简单 保持井然有序&#xff08;有组织的&#xff09;经常测试 git工作原理 chapter 2编写ymal格式的主机清单 欢迎使用Markdown编辑器 最佳实践 保持简单 使用yaml的原生语法使用自带模块尽量使用专用模块&#xff0c;不…...

python文件打包成exe文件

✅ 一、安装 PyInstaller 打开cmd&#xff0c;输入以下代码 pip install pyinstaller✅ 二、打包指令 比如说你有如下的文件需要打包。 首先复制你的文件所在目录&#xff0c;比如我的是C:\Users\Administrator\Desktop\BearingSearchSystem 在cmd中切换到该目录来&#xf…...

人脸识别系统中的隐私与数据权利保障

首席数据官高鹏律师创作 如今人脸识别技术以其高效、便捷的特性广泛应用于各个领域&#xff0c;从安防监控到移动支付&#xff0c;从门禁系统到社交媒体。然而&#xff0c;这项技术在为我们的生活带来诸多便利的同时&#xff0c;也引发了一系列关于隐私与数据权利的深刻担忧。…...

电脑关机再开机会换IP吗?深入解析分配机制

在日常使用电脑时&#xff0c;许多用户可能会好奇&#xff1a;‌关机后再开机&#xff0c;IP地址会不会变化&#xff1f;‌ 这个问题看似简单&#xff0c;但实际上涉及多个因素。本文将详细解析电脑IP地址的变化机制&#xff0c;帮助大家理解其中的原理&#xff0c;并提供相关的…...

经典中的经典-比特币白皮书中文版

AI是一切假的集合&#xff0c;如果任凭AI如此聪明下去&#xff0c;所有的人都将被AI愚弄与股掌之间&#xff0c;那么能限制AI的只有区块链这个让一切数据都无处遁形的真神&#xff0c;而比特币作为区块链的鼻祖&#xff0c;开创了公开账本的先河&#xff0c;当互联网上所有的信…...

Spring事务失效的全面剖析

文章目录 1. Spring事务基础1.1 什么是Spring事务1.2 Spring事务的实现原理1.3 `@Transactional`注解的主要属性1.4 使用Spring事务的简单示例2. Spring事务失效的常见场景及解决方案2.1 方法不是public的问题描述问题示例解决方案技术原理解释2.2 自调用问题(同一个类中的方法…...

本地的ip实现https访问-OpenSSL安装+ssl正式的生成(Windows 系统)

1.下载OpenSSL软件 网站地址&#xff1a;Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions 安装: 一直点击下一步就可以了 2.设置环境变量 在开始菜单右键「此电脑」→「属性」→「高级系统设置」→「环境变量」 在Path 中添加一个: xxxx\OpenSSL-…...

【go】binary包,大小端理解,read,write使用,自实现TCP封包拆包案例

binary.LittleEndian 是 Go 语言 encoding/binary 包中的一个常量&#xff0c;用于指定字节序&#xff08;Byte Order&#xff09;。字节序是指多字节数据在内存中存储的顺序&#xff0c;有两种主要方式&#xff1a; 小端序&#xff08;Little Endian&#xff09;&#xff1a;…...

[万字]qqbot开发记录,部署真寻bot+自编插件

这是我成功部署真寻bot以及实现一个自己编写的插件&#xff08;连接deepseek回复内容&#xff09;的详细记录&#xff0c;几乎每一步都有截图。 正文&#xff1a; 我想玩玩qqbot。为了避免重复造轮子&#xff0c;首先选一个github的高星项目作为基础吧。 看了一眼感觉真寻bot不…...

国内USB IP商业解决方案新选择:硬件USB Server

在数字化办公日益普及的今天&#xff0c;USB OVER NETWORK技术&#xff0c;即USB IP技术&#xff0c;为企业带来了前所未有的便捷与高效。作为这一领域的佼佼者&#xff0c;朝天椒USB Server以其卓越的性能和贴心的设计&#xff0c;正逐步成为众多中国企业的首选USB IP商业解决…...

百度导航广告“焊死”东鹏特饮:商业底线失守,用户安全成隐忧

近日&#xff0c;百度地图因导航时植入“广告”的问题登上社交媒体热搜&#xff0c;并引发广泛争议。 截图自微博 导航途中出现“焊死”在路面的广告 安全隐患引争议 多位网友发帖称&#xff0c;在使用百度地图导航时&#xff0c;导航界面中的公路路面上出现了“累了困了喝东…...

yolo11n-obb训练rknn模型

必备&#xff1a; 准备一台ubuntu22的服务器或者虚拟机&#xff08;x86_64&#xff09; 1、数据集标注&#xff1a; 1&#xff09;推荐使用X-AnyLabeling标注工具 2&#xff09;标注选【旋转框】 3&#xff09;可选AI标注&#xff0c;再手动补充&#xff0c;提高标注速度 …...

GNU Screen 曝多漏洞:本地提权与终端劫持风险浮现

SUSE安全团队全面审计发现&#xff0c;广泛使用的终端复用工具GNU Screen存在一系列严重漏洞&#xff0c;包括可导致本地提权至root权限的缺陷。这些问题同时影响最新的Screen 5.0.0版本和更普遍部署的Screen 4.9.x版本&#xff0c;具体影响范围取决于发行版配置。 尽管GNU Sc…...

无人机避障——如何利用MinumSnap进行对速度、加速度进行优化的轨迹生成(附C++python代码)

&#x1f525;轨迹规划领域的 “YYDS”——minimum snap&#xff01;作为基于优化的二次规划经典&#xff0c;它是无人机、自动驾驶轨迹规划论文必引的 “开山之作”。从优化目标函数到变量曲线表达&#xff0c;各路大神疯狂 “魔改”&#xff0c;衍生出无数创新方案。 &#…...

2025 3D工业相机选型及推荐

3D工业相机是专门为工业应用设计的三维视觉采集设备&#xff0c;能够获取物体的三维空间信息&#xff0c;在智能制造、质量检测、机器人引导等领域有广泛应用。 一、主要类型 1.结构光3D相机 通过投射特定光斑或条纹图案并分析变形来重建三维形状 典型代表&#xff1a;双目结构…...

芋道(yudao-cloud)项目,后端接口报401-账号未登录解决方案

一、需求 最近公司有新的业务需求&#xff0c;调研了一下&#xff0c;决定使用芋道&#xff08;yudao-cloud&#xff09;框架,于是从github&#xff08;https://github.com/YunaiV/yudao-cloud&#xff09;上克隆项目&#xff0c;选用的是jdk17版本的。根据项目启动手册&#…...

动态域名服务ddns怎么设置?如何使用路由器动态域名解析让外网访问内网?

设置路由器的动态域名解析&#xff08;DDNS&#xff09;&#xff0c;通常需先选择支持 DDNS 的路由器和提供 DDNS 服务的平台&#xff0c;然后在路由器管理界面中找到 DDNS 相关设置选项&#xff0c;填入在服务平台注册的账号信息&#xff0c;完成配置后保存设置并等待生效。 …...

论文《Collaboration-Aware Graph Convolutional Network for Recommender Systems》阅读

论文《Collaboration-Aware Graph Convolutional Network for Recommender Systems》阅读 论文概况Introduction and MotivationMethodologyLightGCN 传播形式CIRCAGCNImplementation Experiments 论文概况 论文《Collaboration-Aware Graph Convolutional Network for Recomm…...

Codis集群搭建和集成使用的详细步骤示例

以下是Codis集群搭建和集成使用的详细步骤示例&#xff1a; 环境准备 安装Go语言环境 下载并安装适配操作系统的Go语言版本。配置环境变量GOROOT和GOPATH。 安装ZooKeeper 下载ZooKeeper压缩包&#xff0c;解压并进入目录。复制conf/zoo_sample.cfg为conf/zoo.cfg。启动ZooKe…...

利用比较预言机处理模糊的偏好数据

论文标题 ComPO:Preference Alignment via Comparison Oracles 论文地址 https://arxiv.org/pdf/2505.05465 模型地址 https://huggingface.co/ComparisonPO 作者背景 哥伦比亚大学&#xff0c;纽约大学&#xff0c;达摩院 动机 DPO算法直接利用标注好的数据来做偏好对…...

《数据库原理》部分习题解析

《数据库原理》部分习题解析 1. 课本pg196.第1题。 &#xff08;1&#xff09;函数依赖 若对关系模式 R(U) 的任何可能的关系 r&#xff0c;对于任意两个元组 t₁ 和 t₂&#xff0c;若 t₁[X] t₂[X]&#xff0c;则必须有 t₁[Y] t₂[Y]&#xff0c;则称属性集 Y 函数依赖…...

【HCIA】浮动路由

前言 我们通常会在出口路由器配置静态路由去规定流量进入互联网默认应该去往哪里。那么&#xff0c;如果有两个运营商的路由器都能为我们提供上网服务&#xff0c;我们应该如何配置默认路由呢&#xff1f;浮动路由又是怎么一回事呢&#xff1f; 文章目录 前言1. 网络拓扑图2. …...

基于机器学习的卫星钟差预测方法研究HPSO-BP

摘要 本文研究了三种机器学习方法&#xff08;BP神经网络、随机森林和支持向量机&#xff09;在卫星钟差预测中的应用。通过处理GPS和GRACE卫星的钟差数据&#xff0c;构建了时间序列预测模型&#xff0c;并比较了不同方法的预测性能。实验结果表明&#xff0c;优化后的BP神经…...

机器学习中分类模型的常用评价指标

评价指标是针对模型性能优劣的一个定量指标。 一种评价指标只能反映模型一部分性能&#xff0c;如果选择的评价指标不合理&#xff0c;那么可能会得出错误的结论&#xff0c;故而应该针对具体的数据、模型选取不同的的评价指标。 本文将详细介绍机器学习分类任务的常用评价指…...

AI 检测原创论文:技术迷思与教育本质的悖论思考

当高校将 AI 写作检测工具作为学术诚信的 "电子判官"&#xff0c;一场由技术理性引发的教育异化正在悄然上演。GPT-4 检测工具将人类创作的论文误判为 AI 生成的概率高达 23%&#xff08;斯坦福大学 2024 年研究数据&#xff09;&#xff0c;这种 "以 AI 制 AI&…...

langchain学习

无门槛免费申请OpenAI ChatGPT API搭建自己的ChatGPT聊天工具 https://nuowa.net/872 基本概念 LangChain 能解决大模型的两个痛点&#xff0c;包括模型接口复杂、输入长度受限离不开自己精心设计的模块。根据LangChain 的最新文档&#xff0c;目前在 LangChain 中一共有六大…...

蓝桥杯 10. 全球变暖

全球变暖 原题目链接 题目描述 你有一张某海域 N x N 像素的照片&#xff1a; . 表示海洋# 表示陆地 例如如下所示&#xff1a; ....... .##.... .##.... ....##. ..####. ...###. .......在照片中&#xff0c;“上下左右”四个方向上连在一起的一片陆地组成一座岛屿。例…...

OpenTiny icons——超轻量的CSS图标库,引领图标库新风向

我们非常高兴地宣布 opentiny/icons 正式发布啦&#xff01; 源码&#xff1a;https://github.com/opentiny/icons&#xff08;欢迎 Star ⭐&#xff09; 官网&#xff1a;https://opentiny.github.io/icons/ 图标预览&#xff1a;https://opentiny.github.io/icons/brow…...

python使用OpenCV 库将视频拆解为帧并保存为图片

python使用OpenCV 库将视频拆解为帧并保存为图片 import cv2 import osdef video_to_frames(video_path, output_folder, frame_prefixframe_, interval1, target_sizeNone, grayscaleFalse):"""将视频拆分为帧并保存为图片参数:video_path (str): 视频文件路径…...

[论文阅读]ControlNET: A Firewall for RAG-based LLM System

ControlNET: A Firewall for RAG-based LLM System [2504.09593] ControlNET: A Firewall for RAG-based LLM System RAG存在数据泄露风险和数据投毒风险。相关研究探索了提示注入和投毒攻击&#xff0c;但是在控制出入查询流以减轻威胁方面存在不足 文章提出一种ai防火墙CO…...

机器学习 --- 数据集

机器学习 — 数据集 文章目录 机器学习 --- 数据集一&#xff0c;sklearn数据集介绍二&#xff0c;sklearn现实世界数据集介绍三&#xff0c;sklearn加载数据集3.1 加载鸢尾花数据集3.2 加载糖尿病数据集3.3 加载葡萄酒数据集 四&#xff0c;sklearn获取现实世界数据集五&#…...

在Ubuntu服务器上部署Label Studio

一、拉取镜像 docker pull heartexlabs/label-studio:latest 二、启动容器 &#xff08;回到用户目录&#xff0c;例&#xff1a;输入pwd&#xff0c;显示 /home/<user>&#xff09; docker run -d --name label-studio -it -p 8081:8080 -v $(pwd)/mydata:/label-st…...

机器学习07-归一化与标准化

归一化与标准化 一、基本概念 归一化&#xff08;Normalization&#xff09; 定义&#xff1a;将数据缩放到一个固定的区间&#xff0c;通常是[0,1]或[-1,1]&#xff0c;以消除不同特征之间的量纲影响和数值范围差异。公式&#xff1a;对于数据 ( x )&#xff0c;归一化后的值…...

用vue和go实现登录加密

前端使用CryptoJS默认加密方法&#xff1a; var pass CryptoJS.AES.encrypt(formData.password, key.value).toString()使用 CryptoJS.AES.encrypt() 时不指定加密模式和参数时&#xff0c;CryptoJS 默认会执行以下操作 var encrypted CryptoJS.AES.encrypt("明文&quo…...

服务器制造业中,L2、L6、L10等表示什么意思

在服务器制造业中&#xff0c;L2、L6、L10等是用于描述服务器生产流程集成度的分级体系&#xff0c;从基础零件到完整机架系统共分为L1-L12共12个等级。不同等级对应不同的生产环节和交付形态&#xff0c;以下是核心级别的具体含义&#xff1a; L2&#xff08;Level 2&#xf…...

mysql8常用sql语句

查询结果带行号 -- 表名为 mi_user&#xff0c; 假设包含列 id &#xff0c;address SELECT ROW_NUMBER() OVER (ORDER BY id) AS row_num, t.id, t.address FROM mi_user t ; SELECT ROW_NUMBER() OVER ( ) AS row_num, t.id, t.address FROM mi_user t ; 更新某列数…...

多模态RAG与LlamaIndex——1.deepresearch调研

摘要 关键点&#xff1a; 多模态RAG技术通过结合文本、图像、表格和视频等多种数据类型&#xff0c;扩展了传统RAG&#xff08;检索增强生成&#xff09;的功能。LlamaIndex是一个开源框架&#xff0c;支持多模态RAG&#xff0c;提供处理文本和图像的模型、嵌入和索引功能。研…...