C++进阶——map和set的使用
目录
1、序列式容器和关联式容器
2、set系列的使用
2.1 set和multiset的参考文档
2.2 set类的介绍
2.3 set的构造和迭代器
2.4 set的增删查
2.5 set的insert和迭代器遍历
2.6 set的find和erase
2.7 set的lower_bound和upper_bound
2.8 multiset和set的差异
2.9 349. 两个数组的交集 - 力扣(LeetCode)
2.10 142. 环形链表 II - 力扣(LeetCode)
3、map系列的使用
3.1 map和multimap的参考文档
3.2 map类的介绍
3.3 pair类型的介绍
3.4 map的构造和迭代器
3.5 map的增删查
3.6 map的数据修改
3.7 map的构造遍历及增删查
3.8 map的迭代器和[ ]
3.9 multimap和map的差异
3.10 138. 随机链表的复制 - 力扣(LeetCode)
3.11 692. 前K个高频单词 - 力扣(LeetCode)
1、序列式容器和关联式容器
前面我们已经接触过STL中的部分容器如:string、vector、list、deque、array、forward_list等,这些容器统称为序列式容器,因为逻辑结构为线性结构,两个位置存储的值之间一般没有紧密的关联关系,比如交换一下,他依旧是序列式容器。序列式容器中的元素是按他们在容器中的存储位置(插入位置)来顺序保存和访问的。
关联式容器的逻辑结构通常是非线性结构, 两个位置有紧密的关联关系,交换⼀下,他的存储结构就被破坏了。序列式容器中的元素是按关键字(key)来保存和访问的。关联式容器有map/set系列和unordered_map/unordered_set系列。 本节讲解的map和set底层是红黑树,红黑树是一颗平衡二叉搜索树。set是key搜索场景的结构, map是key/value搜索场景的结构。
2、set系列的使用
2.1 set和multiset的参考文档
<set> - C++ Reference
2.2 set类的介绍
1. set的声明如下,T就是set底层关键字key的类型。
2. set 默认要求key支持小于比较(升序),如果不支持或者想按自己的需求走可以自行实现仿函数传给第二个模版参数。
3. set底层存储数据的内存是从空间配置器申请的,如果需要可以自己实现内存池,传给第三个参 数。
4. 一般情况下,我们都不需要传后两个模版参数。
5. set底层是用红黑树实现,增删查效率是O(logN)。迭代器遍历走的是搜索树的中序,所以是有序。
template < class T, // set::key_type/value_type // 为了和map保持一致class Compare = less<T>, // set::key_compare/value_compareclass Alloc = allocator<T> // set::allocator_type
> class set;
2.3 set的构造和迭代器
set的支持正向和反向 迭代遍历(即双向),支持迭代器就意味着支持范围for。
set不支持修改key数据,修改关键字数据,会破坏底层搜索树的性质。
// empty (1) 无参默认构造
explicit set(const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());// range (2) 迭代器区间构造
template <class InputIterator>
set(InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type & = allocator_type());// copy (3) 拷贝构造
set(const set& x);// initializer list (5) initializer 列表构造
set(initializer_list<value_type> il,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());// 迭代器是一个双向迭代器
iterator -> a bidirectional iterator to const value_type// 正向迭代器
iterator begin();
iterator end();// 反向迭代器
reverse_iterator rbegin();
reverse_iterator rend();
2.4 set的增删查
set的增删查关注以下几个接口即可:
// Member types
key_type -> The first template parameter(T)
value_type -> The first template parameter(T)// 单个数据插入,如果已经存在则插入失败
pair<iterator, bool> insert(const value_type& val);// 列表插入,已经在容器中存在的值不会插入
void insert(initializer_list<value_type> il);// 迭代器区间插入,已经在容器中存在的值不会插入
template <class InputIterator>
void insert(InputIterator first, InputIterator last);// 查找val,返回val所在的迭代器,没有找到返回end()
iterator find(const value_type& val);// 查找val,返回val的个数
size_type count(const value_type& val) const;// 删除一个迭代器位置的值
iterator erase(const_iterator position);// 删除val,val不存在返回0,存在返回1
size_type erase(const value_type & val);// 删除一段迭代器区间的值
iterator erase(const_iterator first, const_iterator last);// 返回 >=val 位置的迭代器
iterator lower_bound(const value_type& val) const;// 返回 >val 位置的迭代器
iterator upper_bound(const value_type& val) const;
2.5 set的insert和迭代器遍历
#include <iostream>
#include <set>using namespace std;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;
}
2.6 set的find和erase
#include <iostream>
#include <set>using namespace std;int main()
{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;// 直接删除xint x;cin >> x;int num = s.erase(x);if (num == 0){cout << x << "不存在!" << endl;}for (auto e : s){cout << e << " ";}cout << endl;int y;// 查找,再利用迭代器删除ycin >> y;auto pos = s.find(y);if (pos != s.end()){s.erase(pos);}else{cout << x << "不存在!" << endl;}for (auto e : s){cout << e << " ";}cout << endl;// 算法库的查找O(N)auto pos1 = find(s.begin(), s.end(), x);// set自身实现的查找O(logN)auto pos2 = s.find(x);// 利用count间接实现快速查找cin >> x;if (s.count(x)){cout << x << "在!" << endl;}else{cout << x << "不存在!" << endl;}return 0;
}
2.7 set的lower_bound和upper_bound
#include <iostream>
#include <set>using namespace std;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]的区间// C++区间必须是必须是左闭右开,如果是[ ],通过以下方式,转成[ )// 返回>= 30auto itlow = myset.lower_bound(30);// 返回> 60auto itup = myset.upper_bound(60);// 删除这段区间的值myset.erase(itlow, itup);for (auto e : myset){cout << e << " ";}cout << endl;return 0;
}
2.8 multiset和set的差异
multiset和set的使用基本类似,主要区别点在于multiset支持冗余,那么 insert/find/count/erase都围绕着支持冗余有所差异。
#include <iostream>
#include <set>using namespace std;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;// 相比set不同的是,x可能会存在多个,find查找中序的第一个int x;cin >> x;auto pos = s.find(x);while (pos != s.end() && *pos == x){cout << *pos << " ";++pos;}cout << endl;// 相比set不同的是,count会返回x的实际个数cout << s.count(x) << endl;// 相比set不同的是,erase给值时会删除所有的xs.erase(x);for (auto e : s){cout << e << " ";}cout << endl;return 0;
}
2.9 349. 两个数组的交集 - 力扣(LeetCode)
思路:
set(去重+排序) + 双指针
class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {set<int> s1(nums1.begin(),nums1.end());set<int> s2(nums2.begin(),nums2.end());vector<int> v;auto it1 = s1.begin();auto it2 = s2.begin();while(it1 != s1.end() &&it2 != s2.end()){if(*it1<*it2)++it1;else if(*it1>*it2)++it2;else{v.push_back(*it1);++it1;++it2;}}return v;}
};
2.10 142. 环形链表 II - 力扣(LeetCode)
思路:
set.count()的返回值充当查找的功能。
class Solution {
public:ListNode *detectCycle(ListNode *head) {set<ListNode*> s;ListNode* cur = head;while(cur){if(s.count(cur) == 0)s.insert(cur);elsereturn cur;cur = cur->next;}return nullptr;}
};
3、map系列的使用
3.1 map和multimap的参考文档
<map> - C++ Reference
3.2 map类的介绍
1. map的声明如下,Key就是map底层关键字key的类型,T是map底层value的类型。
2. map 默认要求key支持小于比较(升序),如果不支持或者需要的话可以自行实现仿函数传给第二个模版参数。
3. map底层存储数据的内存是从空间配置器申请的,如果需要可以自己实现内存池,传给第三个参 数。
4. 一般情况下,我们都不需要传后两个模版参数。
5. map 底层是用红黑树实现,增删查改效率是 O(logN)。迭代器遍历走的是搜索树的中序,所以是按key有序。
template < class Key, // map::key_typeclass T, // map::mapped_typeclass Compare = less<Key>, // map::key_compareclass Alloc = allocator < pair<const Key, T> >//map::allocator_type> class map;
3.3 pair类型的介绍
map底层的红黑树节点中的数据,使用pair存储 键值对 数据。
typedef pair<const Key, T> value_type;// pair 类模板
template <class T1, class T2>
struct pair
{typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair() : first(T1()), second(T2()){}pair(const T1& a, const T2& b) : first(a), second(b){}// 更加通用,允许从不同类型的 pair 对象进行构造template<class U, class V> pair(const pair<U, V>& pr) : first(pr.first), second(pr.second){}
};// make_pair 函数模板
template <class T1, class T2>
inline pair<T1, T2> make_pair(T1 x, T2 y)
{return (pair<T1, T2>(x, y));
}
3.4 map的构造和迭代器
map的支持正向和反向 迭代遍历(即双向),支持迭代器就意味着⽀持范围for。
map支持修改value数据,不支持修改key数据,修改关键字数据,破坏了底层搜索树的结构。
// empty (1) 无参默认构造
explicit map(const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());// range (2) 迭代器区间构造
template <class InputIterator>
map(InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type & = allocator_type());// copy (3) 拷贝构造
map(const map& x);// initializer list (5) initializer 列表构造
map(initializer_list<value_type> il,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());// 迭代器是一个双向迭代器
iterator -> a bidirectional iterator to const value_type// 正向迭代器
iterator begin();
iterator end();// 反向迭代器
reverse_iterator rbegin();
reverse_iterator rend();
3.5 map的增删查
map的增删查关注以下几个接口即可:
map插入的是pair键值对数据,跟set所有不同,但是查和删的接口只用关键字key跟set是完全类似的,不过find返回iterator(pair指针),不仅仅可以确认key在不在,修改到key映射的value。
// Member types
key_type->The first template parameter(Key)
mapped_type->The second template parameter(T)value_type->pair<const key_type, mapped_type>// 单个数据插入,如果存在key则插入失败
pair<iterator, bool> insert(const value_type& val);// 列表插入,已经在容器中存在key.那么这个pair不会插入
void insert(initializer_list<value_type> il);// 迭代器区间插⼊,已经在容器中存在key.那么这个pair不会插入
template <class InputIterator>
void insert(InputIterator first, InputIterator last);// 查找k,返回k所在的迭代器,没有找到返回end()
iterator find(const key_type& k);// 查找k,返回k的个数
size_type count(const key_type& k) const;// 删除一个迭代器位置的值
iterator erase(const_iterator position);// 删除k,k存在返回0,存在返回1
size_type erase(const key_type & k);// 删除一段迭代器区间的值
iterator erase(const_iterator first, const_iterator last);
3.6 map的数据修改
map支持修改mapped_type数据,不支持修改key数据,修改关键字数据,会破坏底层搜索树的结构。
map 第一个支持修改的方式是通过迭代器,迭代器遍历时或者find返回key所在的iterator修改。
map 还有一个非常重要的修改接口 operator[ ],但是operator[ ]不仅仅支持修改,还支持插入数据和查找数据,所以他是一个多功能复合接口。
// Member types
key_type->The first template parameter(Key)
mapped_type->The second template parameter(T)
value_type->pair<const key_type, mapped_type>// 查找k,返回k所在的迭代器,没有找到返回end(),如果找到了通过iterator可以修改key对应的mapped_type值
iterator find(const key_type& k);// insert插入一个pair<key, T>对象// 1、如果key已经在map中,插入失败,则返回一个pair<iterator, bool>对象,
// iterator是key所在结点的迭代器,false// 2、如果key不存在map中,插入成功,则返回一个pair<iterator, bool>对象,
// iterator是新插入key所在结点的迭代器,true// 那么也就意味着insert插入失败时充当了查找的功能,因此,insert可以用来实现operator[]// 注意:这里有两个pair,一个是map底层红黑树节点中存的pair<key, T>,另一个是insert返回值pair<iterator, bool>
pair<iterator, bool> insert(const value_type & val);// operator的内部实现
mapped_type& operator[] (const key_type& k)
{// 1、如果k不在map中,insert会插入k和mapped_type默认值// 同时[]返回结点中存储mapped_type值的引用// 所以[]具备了插入+修改功能// 2、如果k在map中,insert会插入失败,但是insert返回pair对象的first是指向key结点的迭代器// 同时[]返回结点中存储mapped_type值的引用// 所以[]具备了查找+修改的功能pair<iterator, bool> ret = insert({ k, mapped_type() });iterator it = ret.first;return it->second;
}
3.7 map的构造遍历及增删查
#include<iostream>
#include<map>using namespace std;int main()
{// initializer_list构造及迭代遍历map<string, string> dict = { {"left", "左边"}, {"right", "右边"}, {"insert", "插入"},{ "string", "字符串" } };//map<string, string>::iterator it = dict.begin();auto it = dict.begin();while (it != dict.end()){//cout << (*it).first <<":"<<(*it).second << endl;// map的迭代基本都使用operator->,这里省略了一个->// 第一个->是迭代器运算符重载,返回pair*,第二个箭头是结构指针解引用取pair数据//cout << it.operator->()->first << ":" << it.operator->()->second << endl;cout << it->first << ":" << it->second << endl;++it;}cout << endl;string str;while (cin >> str){auto ret = dict.find(str);if (ret != dict.end()){cout << "->" << ret->second << endl;}else{cout << "无此单词,请重新输入" << endl;}}// insert插入pair对象的4种方式,对比之下,最后一种最方便pair<string, string> kv1("first", "第一个");dict.insert(kv1);dict.insert(pair<string, string>("second", "第二个"));dict.insert(make_pair("third", "第三个"));dict.insert({ "fourth", "第四个" });// 范围for遍历for (const auto& e : dict){cout << e.first << ":" << e.second << endl;}cout << endl;// erase等接口跟set完全类似,这里就不演时讲解了return 0;
}
3.8 map的迭代器和[ ]
#include<iostream>
#include<map>using namespace std;int main()
{// 利用find和iterator修改功能,统计水果出现的次数string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果","西瓜", "苹果", "香蕉", "苹果", "香蕉" };map<string, int> countMap1;for (const auto& str : arr){// 先查找水果在不在map中// 1、不在,说明水果第一次出现,则插入{水果, 1}// 2、在,则查找到的节点中水果对应的次数++auto ret = countMap1.find(str);if (ret == countMap1.end()){countMap1.insert({ str, 1 });}else{ret->second++;}}for (const auto& e : countMap1){cout << e.first << ":" << e.second << endl;}cout << endl;// 利用[ ]插入+修改功能,巧妙实现统计水果出现的次数map<string, int> countMap2;for (const auto& str : arr){// [ ]先查找水果在不在map中// 1、不在,说明⽔果第一次出现,则插入{水果, 0 },同时返回次数的引用,++一下就变成1次了// 2、在,则返回水果对应的次数++countMap2[str]++;}for (const auto& e : countMap2){cout << e.first << ":" << e.second << endl;}cout << endl;return 0;
}
3.9 multimap和map的差异
multimap和map的使用基本类似,主要区别点在于multimap支持关键值key冗余。
那么insert/find/count/erase都围绕着支持关键值key冗余有所差异,这里跟set和multiset完全一样。
如 find 时,有多个key,返回中序第一个。其次就是multimap不支持[ ],因为支持key冗余。
3.10 138. 随机链表的复制 - 力扣(LeetCode)
思路1:
A→A′→B→B′→C→C′
写的时候,注意先保存,链表头 尾连接的情况。head要经常用,使用不直接使用head。
class Solution {
public:Node* copyRandomList(Node* head) {if(head == nullptr)return nullptr;Node* cur = head;while(cur){Node* node = new Node(cur->val);Node* tmp = cur->next; // 先保存原节点的next// 连接节点cur->next = node;node->next = tmp;cur = tmp;}cur = head;while(cur){if(cur->random)cur->next->random = cur->random->next;elsecur->next->random = nullptr;cur = cur->next->next;}cur = head;Node* h = head->next; // 保存拷贝链表的头节点while(cur){Node* node = cur->next; // 先保存拷贝节点// 原链表连接cur->next = node->next;cur = cur->next;// 拷贝链表连接if(cur) // 原链表cur为nullptr,单独处理node->next = cur->next;elsenode->next = nullptr;}return h;}
};
思路2:
map<Node*,Node*>,对应拷贝,拷贝的节点的next和random,注意一下nullptr。
class Solution {
public:Node* copyRandomList(Node* head) {if(head == nullptr)return nullptr;map<Node*,Node*> mp;Node* cur = head;while(cur){mp.insert({cur,new Node(cur->val)});cur = cur->next;}auto it = mp.begin();while(it != mp.end()){if(it->first->next)it->second->next = mp[it->first->next];elseit->second->next = nullptr;if(it->first->random)it->second->random = mp[it->first->random];elseit->second->random = nullptr;++it;}return mp[head];}
};
3.11 692. 前K个高频单词 - 力扣(LeetCode)
思路一:
map<string,int>,会按string(key)默认升序,sort需要随机迭代器,先转成vector,排序时改变sort的比较方式,使其稳定,或者直接使用stable_sort(稳定的排序,应该是希尔排序)。
class Solution {
public:struct Compare{bool operator()(const pair<string,int>& p1,const pair<string,int>& p2){return p1.second>p2.second||p1.second==p2.second&&p1.first<p2.first;}};vector<string> topKFrequent(vector<string>& words, int k) {map<string,int> mp;for(const auto& e:words){++mp[e];}vector<pair<string,int>> v(mp.begin(),mp.end());sort(v.begin(),v.end(),Compare());vector<string> ans;for(int i = 0;i<k;++i){ans.push_back(v[i].first);}return ans;}
};
相关文章:
C++进阶——map和set的使用
目录 1、序列式容器和关联式容器 2、set系列的使用 2.1 set和multiset的参考文档 2.2 set类的介绍 2.3 set的构造和迭代器 2.4 set的增删查 2.5 set的insert和迭代器遍历 2.6 set的find和erase 2.7 set的lower_bound和upper_bound 2.8 multiset和set的差异 2.9 349.…...
AI机器学习---Anaconda
Anaconda指的是一个开源的Python发行版本,其包含了Conda、Python等180多个科学包及其依赖项。因为包含了大量的科学包,Anaconda 的下载文件比较大(约 531 MB),如果只需要某些包,或者需要节省带宽或存储空间…...
如何在Futter开发中做性能优化?
目录 1. 避免不必要的Widget重建 问题:频繁调用setState()导致整个Widget树重建。 优化策略: 2. 高效处理长列表 问题:ListView一次性加载所有子项导致内存暴涨。 优化策略: 3. 图片加载优化 问题:加载高分辨率…...
leetcode 75.颜色分类(荷兰国旗问题)
题目描述 题目分析 本题是经典的「荷兰国旗问题」,由计算机科学家 Edsger W. Dijkstra 首先提出。 要想单独解决这道题本身还是很简单的,统计0、1、2的数量然后按顺序赋值,或者手写一个冒泡排序,whatever。 但是在这一题中我们主…...
JVM--垃圾回收
垃圾回收的概念 垃圾回收主要针对的是堆中的对象,堆是一个共享的区域,创建的对象和数组都放在这个位置。但是我们不能一直的创建对象,也不是所有的对象能一直存放,如果不进行垃圾回收,内存迟早会耗尽,及时…...
Spring boot3-Http Interface: 声明式编程
来吧 1.首先引入pom.xml依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId> </dependency> 2.创建WebClientController控制器 import com.atguigu.boot3_07_http.serv…...
springboot EasyExcel 实现导入导出
1. 添加依赖 确保 Maven 依赖中包含 EasyExcel 3.0.5: <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version></dependency><!-- excel工具 --><dep…...
基于RAGFlow本地部署DeepSpeek-R1大模型与知识库:从配置到应用的全流程解析
作者:后端小肥肠 🍊 有疑问可私信或评论区联系我。 🥑 创作不易未经允许严禁转载。 姊妹篇: DeepSpeek服务器繁忙?这几种替代方案帮你流畅使用!(附本地部署教程)-CSDN博客 10分钟上手…...
spring 创建单例 Bean 源码分析
一、创建单例Bean 1、创建单例 Bean 通过方法getBean()来创建单例bean。 代码入口: org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons spring boot version:2.6.13 org.springframework.beans.factory…...
GetCurrentTime
在实际编程中难免要获取当前时间并且进行格式化,本文给出了多种 GetCurrentTime() 方法以供选择。 C语言下使用strftime C 语言中可以使用 <time.h> 中的函数来获取和格式化时间 #include <stdio.h> #include <time.h>char* getCurrentTime() …...
HTB 学习笔记 【中/英】《Web 应用简介》P1
📌 这篇文章讲了什么? 介绍了 Web 应用 的概念、架构,以及与传统网站的区别。重点讲解了 Web 安全风险,包括 常见攻击方法(SQL 注入、文件包含、不安全的文件上传等)。介绍了 Web 渗透测试 的重要性&#…...
ROS catkin_make编译报错问题
对问题 CMake Error at graduation_design/CMakeLists.txt:226 (add_dependencies): The dependency target "graduation_design_generate_messages_cpp" of target "listener" does not exist 检查 generate_messages() 是否被注释 对 CMake Error at …...
【结构设计】3D打印创想三维Ender 3 v2
【结构设计】3D打印创想三维Ender 3 v2 文章目录 前言一、Creality Slicer1.2.3打印参数设置二、配件更换1.捆扎绑扎线2.气动接头3D打印机配件插头3.3D打印机配件Ender3pro/V2喷头套件4.读卡器 TF卡5.micro sd卡 三、调平四、参考文章总结 前言 使用工具: 1.创想三…...
并发编程2
接并发编程1 synchronized锁的实现 通过底层指令控制实现,Java提供的一种原子性内置锁,在进入synchronized后会从主内存复制一份共享变量到自己的工作内存,在工作内存中修改完成后,退出时会把工作内存的值写入到主内存ÿ…...
Linux 中 Git 使用指南:从零开始掌握版本控制
目录 1. 什么是 Git? Git 的核心功能: 2. Git 的安装 Ubuntu/Debian 系统: 验证安装: 3.gitee库 4. Git 的首次配置 配置用户名和邮箱: 查看配置: 5. Git 的基本使用 初始化仓库 添加文件到暂存区…...
C# Exe + Web 自动化 (BitComet 绿灯 自动化配置、设置)
BitComet GreenLight,内网黄灯转绿灯 (HighID), 增加p2p连接率提速下载-CSDN博客 前两天写个这个,每次开机关机后要重来一遍很麻烦的索性写个自动化。 先还是按照上面的教程自己制作一遍,留下Luck 以及 路由器相关的 端口记录信息。 (因为自…...
2024年12月CCF-GESP编程能力等级认证C++编程四级真题解析
四级真题的难度: 一、总体难度评价 CCF-GESP编程能力等级认证C++四级真题的难度通常被认为相对较高。它不仅要求考生具备扎实的C++编程基础,还需要考生掌握一定的算法和数据结构知识,以及良好的问题解决能力。 二、具体难度分析 理论知识考察: 单选题和判断题中,会涉…...
谷歌Chrome或微软Edge浏览器修改网页任意内容
在谷歌或微软浏览器按F12,打开开发者工具,切换到console选项卡: 在下面的输入行输入下面的命令回车: document.body.contentEditable"true"效果如下:...
《DeepSeek深度使用教程:开启智能交互新体验》Deepseek深度使用教程
《DeepSeek使用教程:开启智能交互新体验》 在当今数字化时代,人工智能技术正以前所未有的速度改变着我们的生活和工作方式。DeepSeek作为一款强大的人工智能工具,凭借其卓越的自然语言处理能力和多领域应用潜力,受到了众多开发者…...
Dijkstra算法
Dijkstra算法(迪杰斯特拉算法)是一种经典的单源最短路径算法,用于在加权图中找到从一个源点到所有其他顶点的最短路径。它要求图中不能有负权边,因为负权边可能会导致算法的贪心策略失效。 Dijkstra算法的基本思想 Dijkstra算法…...
Python中的静态方法如何使用?
在Python里,类当中的方法可以分为多种不同的类型,其中staticmethod是一个十分有趣而又实用的功能。我们来好好地聊一聊什么是静态方法,它的用途是什么,以及如何在实际应用中使用它们! 首先,定义一下静态方…...
【最后203篇系列】016 Q201架构思考
前言 Q200已经达到了我既定的目标,在最近的3个月,我需要进一步完善,达到可以试产的程度。 在这个过程当中,许多知识和体会一直在变。 qtv200到目前,虽然通过习惯(每晚运行离线策略和比对)方式维持了注意力的集中&…...
小脑萎缩会致命吗?
小脑萎缩,顾名思义,是指小脑的体积减小或结构发生异常,进而影响其正常功能。小脑作为人体重要的协调和运动控制中心,负责维持身体平衡、调节肌肉张力和协调运动等关键功能。当小脑出现萎缩时,患者可能会出现步态不稳、…...
pip install和conda install的区别
这里写目录标题 一、什么是 Python 依赖(Python Dependencies)?1. 依赖的作用2. 如何管理 Python 依赖3. 依赖管理问题4. 依赖锁定总结 二、使用pip安装包venv隔离环境方法 1:使用 venv(推荐)创建虚拟环境激…...
這是我第一次寫關於aapenal服務器管理控制面板的文章
首先我們來認識一下服務器管理面板的所有功能 網站管理功能: 支持創建和管理多個網站。配置虛擬主機(Vhost)和域名綁定。自動安裝常用應用(如WordPress、Joomla等)。 文件管理功能: 文件上傳、…...
requests库的request和response对象的属性和方法
Python requests库 request 参数信息 response 参数信息...
8664蛋糕的美味值
8664蛋糕的美味值 ⭐️难度:中等 🌟考点:枚举 📖 📚 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in );int n sc.nextInt();int k s…...
【MySQL】数据库简要介绍和简单应用
目录 数据库简要介绍 SQL 的简单应用 需要注意的: 数据库简要介绍 数据库(database)是指长期存储在计算机内,有组织的、可共享的数据集合。它可视为一个电子化的文件柜,用来存储电子文件,用户可以对文件中的数据进行査询、新增、更新、删…...
yolo环境 pytorch环境配置 CUDA安装
我的成功案例:首先安装python 3.12.9的conda虚拟环境 (如果不安装3.12的会报错误ModuleNotFoundError:没有名为“numpy._core”的模块) 然后安装11.8cuda (其实我是可以最高安装12.6的cuda但我实测,太高版…...
camellia redis proxy v1.3.3对redis主从进行读写分离(非写死,自动识别故障转移)
1 概述 camellia-redis-proxy是一款高性能的redis代理(https://github.com/netease-im/camellia),使用netty4开发,主要特性如下: 支持代理到redis-standalone、redis-sentinel、redis-cluster。支持其他proxy作为后端…...
python相关语法的学习文档1
python相关语法的学习文档1 1、tqdm tqdm 是 Python 中一个非常流行的进度条库,可以实时显示循环或任务的进度。它简单易用,支持多种场景(如循环、文件处理、多线程/进程等)。以下是详细的使用讲解: 1.1 安装 pip install tqdm1.2 基本用法 from tqdm import tqdm impo…...
Web元件库 ElementUI元件库+后台模板页面(支持Axure9、10、11)
Axure是一款非常强大的原型设计工具,它允许设计师和开发者快速创建高保真原型,以展示应用或网站的设计和功能。通过引入各种元件库,如ElementUI元件库,可以极大地丰富Axure的原型设计能力,使其更加贴近实际开发中的UI组…...
Java 并发编程——BIO NIO AIO 概念
参考 Java 并发编程——BIO NIO AIO 概念 阻塞与非阻塞、同步与异步概念 系统调用、缓存、物理设备阻塞与非阻塞同步与异步 四种主要的 IO 模型 同步阻塞 IO同步非阻塞 IOIO 多路复用异步 IO select,poll,epoll 系统调用命令...
在微信小程序或前端开发中,picker 和 select 都是用户交互中用于选择的组件,但它们在功能、设计和使用场景上有一定的区别
在微信小程序或前端开发中,picker 和 select 都是用户交互中用于选择的组件,但它们在功能、设计和使用场景上有一定的区别。 1. picker 的特点 描述: picker 是微信小程序中的原生组件,通常用于选择单项或多项值,如时…...
笔记本 Win10 部署阿里通义千问 1.5-0.5B 大模型 mini 版
文章目录 1.环境准备1.1 硬件环境1.2 OS 环境1.3 Python 环境 2.环境安装2.1 CUDA 驱动下载安装2.2 torch 库下载安装2.3 transformers 库安装2.3 accelerate 库安装2.4 验证 CUDA 是否可用2.5 下载 Qwen1.5-0.5B 大模型 3.测试大模型3.1 加载大模型3.2 简单对话3.3 亲测体验感…...
SpringBoot事件驱动
1、概述 Spring事件驱动采用了观察者设计模式,主要作用就是实现对象之间的松耦合通信。它的核心思想是通过事件的发布和监听来实现不同组件之间的交互。(跟mq挺像) 基础概念: 事件(Event): 在Spring中&am…...
nginx中间件部署
普通权限账户安装NGINX中间件 1、拥有高级权限的账户安装必要的插件 sudo yum install -y gcc-c make pcre pcre-devel zlib zlib-devel openssl openssl-devel 2、普通账户进行NGINX的脚本式安装 vi nginx_intall.sh #!/bin/bash TAR_NAME"$1" TAR_NAME_DIRba…...
Qt程序基于共享内存读写CodeSys的变量
文章目录 1.背景2.结构体从CodeSys导出后导入到C2.1.将结构体从CodeSys中导出2.2.将结构体从m4文件提取翻译成c格式 3.添加RTTR注册信息4.读取PLC变量值5.更改PLC变量值 1.背景 在文章【基于RTTR在C中实现结构体数据的多层级动态读写】中,我们实现了通过字符串读写…...
vulnhub-Hackme-隧道建立、SQL注入、详细解题、思路清晰。
vulnhub-Hackme-隧道建立、SQL注入、详细解题、思路清晰。 一、信息收集 2025.3.14 PM 12:18 1、主机发现 arp-scan -l nmap -sn 192.168.66.0/24 2、端口扫描 1、nmap --min-rate 10000 -p- 192.168.66.182 -oA port 查看所有开放端口2、map -sS -sV 192.168.6…...
技术-NBIOT
是什么? 窄带物联网(Narrow Band Internet of Things, NB-IoT)成为万物互联网络的一个重要分支支持低功耗设备在广域网的蜂窝数据连接,也被叫作低功耗广域网(LPWAN)NB-IoT支持待机时间长、对网络连接要求较高设备的高效连接NB-Io…...
【论文阅读】AlexNet——深度学习奠基作之一
原文链接 Step 1 1. titleabstract 第一句:告诉我干了什么事情 我们训练了一个很大很深的卷积神经网络,用来对120w个图片作分类,这里面有1000个类 第二句:结果 在测试集上面,top-1 error37.5%,top-517.0…...
【云原生技术】编排与容器的技术演进之路
一、编排与容器的技术演进之路 1.1 DockerClient 此时 K8s 只是编排领域的一个选择,而 Docker 此时一家独大,所以 K8s 的客户端只 是作为 Docker 的客户端来调用 Docker 引擎来完成服务。 1.2 RUNC&Shim OCI催生 runcrunc,剥离 Docke…...
鸿蒙编译框架插件HvigorPlugin接口的用法介绍
鸿蒙系统中HvigorPlugin接口实现自定义编译插件,实现编译前后自定义功能。 在鸿蒙(HarmonyOS)开发中,HvigorPlugin 是用于扩展 Hvigor 构建工具功能的接口。通过实现此接口,开发者可以自定义构建任务、修改构建流程或…...
Springboot+mybatis实现增删改查操作
继续写一下删除操作,删除有些不一样,首先在controller里面,我们需要改一下路由,我们后面要写/{id}传入路径参数,用PathVariable注解绑定id,剩下的都一样,传入id,然后写service和mapp…...
Java中的I/O
1.I/O流 1.1I/O概述 1.2.基本用法 1.3.字节输出流写数据的细节 1.4.FileOutPutStream写数据的三种方式 明天再更~~~~,先混个流量券。...
前端组件封装艺术:设计原则与最佳实践指南
文章目录 一、组件封装的核心原则1.1 设计原则概览1.2 组件生命周期 二、组件设计准则2.1 单一职责原则2.2 高内聚低耦合 三、组件接口设计3.1 Props设计规范3.2 代码示例 四、组件状态管理4.1 状态设计原则4.2 代码示例 五、组件样式处理5.1 样式方案对比5.2 代码示例 六、组件…...
SpringMVC(五)拦截器
目录 拦截器基本概念 一 单个拦截器的执行 1 创建拦截器 2 SpringMVC配置,并指定拦截路径。 3 运行结果展示: 二 多个拦截器的执行顺序 三 拦截器与过滤器的区别 拦截器基本概念 SpringMVC内置拦截器机制,允许在请求被目标方法处理的…...
jupyter无法转换为PDF,HTMLnbconvert failed: Pandoc wasn‘t found.
无法转为PDF 手动下载工具 https://github.com/jgm/pandoc/releases/tag/3.6.3 似乎跟我想的不大一样,还有新的报错 https://nbconvert.readthedocs.io/en/latest/install.html#installing-tex 不知道下的啥玩意儿 sudo apt-get install texlive-xetex texlive-fon…...
【红黑树】—— 我与C++的不解之缘(二十五)
前言 学习了avl树,现在来学习红黑树。 一、什么是红黑树 红黑树是一颗平衡二叉搜索树,它每一个节点增加了一个存储位表示节点的颜色,可以是红色或者黑色。 相比较于AVL树,红黑树也是一个自平衡二叉搜索树,但是它与AVL树…...
机器学习 Day05 pandas库
1.pandas介绍和优点 Pandas 是 2008 年由 Wes McKinney 开发的开源 Python 库 。它专门用于数据挖掘和数据分析,具有以下特点: 数据结构独特:核心数据结构为 Series(一维)和 DataFrame(二维) …...