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

【C++】关联式容器——map和set的使用

文章目录

    • 一、关联式容器
    • 二、键值对
    • 三、树形结构的关联式容器
      • 1.set
      • 2.multiset
      • 3.map
      • 4.multimap
    • 四、题目练习

一、关联式容器

序列式容器📕:已经接触过STL中的部分容器,比如:vector、list、deque、forward_list(C++11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身
关联式容器📕:也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高


二、键值对

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和valuekey代表键值value表示与key对应的信息

比如📝:现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义

SGI-STL中关于键值对的定义 👇

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){}
};

三、树形结构的关联式容器

根据应用场景的不同,STL总共实现了两种不同结构的管理式容器🔴:树型结构与哈希结构

树型结构的关联式容器主要有四种:mapsetmultimapmultiset。这四种容器的共同点是:使用平衡搜索树(即红黑树)
作为其底层结果,容器中的元素是一个有序的序列。

下面,我们一起来看一看这四种关联式容器👇

1.set

\1. set是按照一定次序存储元素的容器
\2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们
\3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序
\4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代
\5. set在底层是用二叉搜索树(红黑树)实现的 ,中序之后自然是有序的,插入元素之后:小的往左边走,大的往右边走,相等则返回false

set的模板参数列表

image-20230209135708399

T: set中存放元素的类型,实际在底层存储<value, value>的键值对。
Compare:仿函数,set中元素默认按照小于来比较
Alloc:set中元素空间的管理方式,使用STL提供的空间配置器管理

set的构造函数

image-20230209140045767

默认构造、迭代器区间构造、拷贝构造(深拷贝):

void test_set()
{int arr[] = { 1,2,3,4,5 };set<int> s;//默认构造set<int> s1(arr, arr + 5);//区间构造set<int> s2(s1);//拷贝构造for (auto e : s1) cout << e << " "; cout << endl;for (auto e : s2) cout << e << " "; cout << endl;}

image-20230209141749230

set的迭代器

函数声明功能介绍
iterator begin() \end()返回set中起始位置元素的迭代器\返回set中最后一个元素后面的迭代器
const_iterator cbegin()\cend() const返回set中起始位置元素的const迭代器\返回set中最后一个元素后面的const迭代器
reverse_iterator rbegin() \rend()返回set第一个元素的反向迭代器,即end\返回set最后一个元素下一个位置的反向迭代器,即 rbegin
const_reverse_iterator crbegin() \crend() const返回set第一个元素的反向const迭代器,即cend\返回set最后一个元素下一个位置的反向const迭代器, 即crbegin

我们简单来看一看代码把:

void test_set1()
{set<int> s;s.insert(1);s.insert(2);s.insert(1);s.insert(3);s.insert(4);s.insert(5);//排序+去重for (auto e : s){cout << e << " ";}cout << endl;//set<int>::iterator it = s.begin();auto it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;}
int main()
{test_set1();return 0;
}

image-20230209084310253

默认是升序,如果是想要降序:使用反向迭代器 仿函数:less👉greater

image-20230209145516913

set的修改操作

find&&erase

image-20230209151218767

image-20230209151253461

对于find和erase我们都是比较熟悉的了,我们可以直接上手代码的实现

void test_set3()
{set<int> s;s.insert(1);s.insert(2);s.insert(1);s.insert(3);s.insert(4);s.insert(5);//set<int>::iterator it = s.begin();auto it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;auto pos = s.find(3);//更快一点点,借助二叉树查找O(logN)//auto pos = find(s.begin(), s.end(), 3);//暴力查找O(N)if (pos != s.end()){s.erase(pos);}s.erase(1);for (auto e : s) cout << e << " ";cout << endl;
}

image-20230209151633971

值得一提的是,set还有一个count接口,count返回个数,可以判断一个值是否存在

image-20230209153334684

image-20230209154918795

但是count不是为此设计的!是为了和multiset容器保持接口的一致性。

2.multiset

\1. multiset是按照特定顺序存储元素的容器,其中元素是可以重复的。
\2. 在multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成的键值对,因此value本身就是key,key就是value,类型为T). multiset元素的值不能在容器中进行修改(因为元素总是const的),但可以从容器中插入或删除。
\3. 在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则进行排序。
\4. multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭代器遍历时会得到一个有序序列。
\5. multiset底层结构为二叉搜索树(红黑树)

上面说了这么多的内容,其实就是与set的区别是👉:multiset中的元素可以重复,set是中value是唯一的

void test_multiset()
{int arr[] = {1,2,3,1,1,6,8};multiset<int> s(arr, arr + sizeof(arr) / sizeof(int));for (auto& e : s){cout << e << " ";}cout << endl;
}

image-20230211104721289

另外,如果有多个值相同,find返回的值是中序的第一个:

void test_multiset()
{int arr[] = {1,2,3,4,5,6,3};multiset<int> s(arr, arr + sizeof(arr) / sizeof(int));for (auto& e : s){cout << e << " ";}cout << endl;auto it = s.find(3);while (it != s.end()){cout << *it << " ";it++;}cout << endl;
}

image-20230211105409298

3.map

\1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
\2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair:typedef pair value_type;
\3. 在内部,map中的元素总是按照键值key进行比较排序的。
\4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
\5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
\6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))

map的模板参数

image-20230209164255934

key: 键值对中key的类型
T:键值对中value的类型
Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器

map的构造

image-20230209201222399

void test_map()
{map<int, int> m;int arr[] = { 1,1,1,2,3,4,5,6 };for (auto& e : arr){m.insert(make_pair(e, e));}map<int, int>m1(m.begin(), m.end());//迭代器区间构造for (auto& e : m1)cout << e.first<<":"<<e.second << " "; cout << endl;map<int, int> m2(m1);//拷贝构造for (auto& e : m2)cout << e.first << ":" << e.second << " "; cout << endl;
}

image-20230209203117851

map的修改

insert插入

image-20230210000921674

void test_map1()
{map<string, string> dict;dict.insert(pair<string, string>("排序", "sort"));dict.insert(pair<string, string>("左边", "left"));dict.insert(pair<string, string>("右边","right"));dict.insert(make_pair("字符串", "string"));map<string, string>::iterator it = dict.begin();//auto it = dict.begin()while (it != dict.end()){//(*it).firstcout << it->first<<":"<<it->second << endl;++it;}cout << endl;for (auto& e : dict){cout << e.first << ":" << e.second << endl;}
}

image-20230210002604154

make_pair:函数模板,不需要像pair一样显示声明类型,而是通过传参自动推导,相比于typedef更好用一些

image-20230210001308473

统计次数

第一种方法:迭代器

void test_map2()
{//统计水果出现的次数string arr[] = { "苹果", "西瓜", "香蕉", "草莓", "苹果", "西瓜", "苹果","苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };map<string, int> countMap;for (auto& e : arr){map<string, int>:: iterator it = countMap.find(e);if (it == countMap.end()){countMap.insert(make_pair(e, 1));}else{it->second++;}}for (const auto& kv : countMap){cout << kv.first << ":" << kv.second << endl;}
}

image-20230210103145333

第二种方法:map[]的使用

void test_map2()
{//统计水果出现的次数string arr[] = { "苹果", "西瓜", "香蕉", "草莓", "苹果", "西瓜", "苹果","苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };map<string, int> countMap;for (auto& e : arr){countMap[e]++;}for (const auto& kv : countMap){cout << kv.first << ":" << kv.second << endl;}
}

image-20230210103401722[]有三个功能:1.插入 2.修改 3.查找给一个key,可以查找在不在,如果不在则可以插入,在的话既可以查找也可以进行修改value

注意[]用的时候要小心,不在的话会偷偷给你插入

下面我们来仔细看一看[]:[]实际上调用的是insert,insert有啥好调用的,我们要关注的是insert的返回值

image-20230210131238825

返回second的别名就可以进行修改了。简单运用一下[]把:

void test_map1()
{map<string, string> dict;dict.insert(pair<string, string>("排序", "sort"));dict.insert(pair<string, string>("左边", "left"));dict.insert(pair<string, string>("右边","right"));dict.insert(make_pair("字符串", "string"));dict["迭代器"] = "iterator";//插入+修改dict["insert"];dict.insert(make_pair("左边", "xxx"));//插入失败,搜索树只会比较keydict["insert"] = "插入";//修改cout << dict["左边"] << endl;//查找:key在就是查找auto it = dict.begin();while (it != dict.end()){cout << it->first<<":"<<it->second << endl;++it;}cout << endl;
}

image-20230210133615486

4.multimap

multimap容器与map容器的底层实现以及成员函数的接口都是基本一致,其中多个键值对之间的key是可以重复的

void test_multimap()
{multimap<string, string> dict;dict.insert(make_pair("left", "左边"));dict.insert(make_pair("left", "左边"));dict.insert(make_pair("right", "右边"));dict.insert(make_pair("sort", "排序"));dict.insert(make_pair("left", "xxx"));map<string, int> countMap;for (auto& kv : dict){cout << kv.first << ":" << kv.second << endl;}cout << endl;
}

image-20230211112606587

multimap并没有[],find()返回中序的第一个,剩下的没什么区别:

void test_multimap()
{multimap<string, string> dict;dict.insert(make_pair("left","左边"));dict.insert(make_pair("right", "右边"));dict.insert(make_pair("sort", "排序"));dict.insert(make_pair("left", "xxx"));map<string, int> countMap;for (auto& kv : dict){cout << kv.first << ":" << kv.second << endl;}cout << endl;
}

multimap同样是可以统计次数的

void test_multimap1()
{multimap<string, int> countMap;string arr[] = { "苹果", "西瓜", "香蕉", "草莓", "苹果", "西瓜", "苹果","苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };for (auto& e : arr){auto it = countMap.find(e);if (it == countMap.end()){countMap.insert(make_pair(e, 1));}else{it->second++;}}for (const auto& kv : countMap){cout << kv.first << ":" << kv.second << endl;}
}

image-20230210135854653

下面做两个题目试一试把👇


四、题目练习

前K个高频单词

image-20230210140910415

给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。

class Solution {
public:class greater{public:bool operator()(const pair<string,int>&l,const pair<string,int>& r){return l.second>r.second||(l.second==r.second&&l.first<r.first);}};vector<string> topKFrequent(vector<string>& words, int k) {unordered_map<string,int> countMap;for(auto&e:words) countMap[e]++;priority_queue<pair<string,int>,vector<pair<string,int>>,greater> pq;for(auto it = countMap.begin();it!=countMap.end();it++){pq.push(*it);if(pq.size()>k)pq.pop();}vector<string> ret;ret.resize(k);for(int i = k-1;i>=0;i--){ret[i] = pq.top().first;pq.pop();}return ret;}
};

两个数组的交集

image-20230211101726355

给定两个数组 nums1nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序

利用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());//比对算法逻辑auto it1 = s1.begin();auto it2 = s2.begin();vector<int> ret;while(it1!=s1.end()&&it2!=s2.end()){if(*it1==*it2){ret.push_back(*it1);it1++;it2++;}else if(*it1>*it2){it2++;}else{it1++;}}return ret;}
};

本篇结束…

相关文章:

【C++】关联式容器——map和set的使用

文章目录一、关联式容器二、键值对三、树形结构的关联式容器1.set2.multiset3.map4.multimap四、题目练习一、关联式容器 序列式容器&#x1f4d5;:已经接触过STL中的部分容器&#xff0c;比如&#xff1a;vector、list、deque、forward_list(C11)等&#xff0c;这些容器统称为…...

Promise的实现原理

作用&#xff1a;异步问题同步化解决方案&#xff0c;解决回调地狱、链式操作原理&#xff1a; 状态&#xff1a;pending、fufilled reject构造函数传入一个函数&#xff0c;resolve进入then&#xff0c;reject进入catch静态方法&#xff1a;resolve reject all any react ne…...

【MFC】数据库操作——ODBC(20)

ODBC:开放式数据库连接&#xff0c;是为解决异构数据库&#xff08;不同数据库采用的数据存储方法不同&#xff09;共享而产生的。ODBC API相对来说非常复杂&#xff0c;这里介绍MFC的ODBC类。 添加ODBC用户DSN 首先&#xff0c;在计算机中添加用户DSN&#xff1a;(WIN10下&a…...

旺店通与金蝶云星空对接集成采购入库单接口

旺店通旗舰奇门与金蝶云星空对接集成采购入库单查询连通销售退货新增V1(12-采购入库单集成方案-P)数据源系统:旺店通旗舰奇门旺店通是北京掌上先机网络科技有限公司旗下品牌&#xff0c;国内的零售云服务提供商&#xff0c;基于云计算SaaS服务模式&#xff0c;以体系化解决方案…...

Linux基础-学会使用命令帮助

概述使用 whatis使用 man查看命令程序路径 which总结参考资料概述Linux 命令及其参数繁多&#xff0c;大多数人都是无法记住全部功能和具体参数意思的。在 linux 终端&#xff0c;面对命令不知道怎么用&#xff0c;或不记得命令的拼写及参数时&#xff0c;我们需要求助于系统的…...

MyBatis 之四(动态SQL之 if、trim、where、set、foreach 标签)

文章目录动态 SQL1. if 标签2. trim 标签3. where 标签4. set 标签5. foreach 标签回顾一下&#xff0c;在上一篇 MyBatis 之三&#xff08;查询操作 占位符#{} 与 ${}、like查询、resultMap、association、collection&#xff09;中&#xff0c;学习了针对查询操作的相关知识点…...

PAT (Advanced Level) Practice 1006 Sign In and Sign Out

1006 Sign In and Sign Out题目翻译代码分数 25作者 CHEN, Yue单位 浙江大学At the beginning of every day, the first person who signs in the computer room will unlock the door, and the last one who signs out will lock the door. Given the records of signing in’…...

Android入门第64天-MVVM下瀑布流界面的完美实现-使用RecyclerView

前言 网上充满着不完善的基于RecyclerView的瀑布流实现&#xff0c;要么根本是错的、要么就是只知其一不知其二、要么就是一充诉了一堆无用代码、要么用的是古老的MVC设计模式。 一个真正的、用户体验类似于淘宝、抖音的瀑布流怎么实现目前基本为无解。因为本人正好自己空闲时也…...

Windows PowerShell中成功进入conda虚拟环境

本人操作系统是Windows10&#xff08;输入命令cmd或在运运行中输入winver查看&#xff09;在cmd命令行中大家都很熟悉&#xff0c;很方便进入到指定创建了的虚拟环境中&#xff0c;那么在PowerShell中怎么进入呢&#xff1f;比如在VSCode中的TERMINAL使用的是PowerShell&#x…...

【C++】类与对象理解和学习(中)

专栏放在【C知识总结】&#xff0c;会持续更新&#xff0c;期待支持&#x1f339;六大默认成员函数前言每个类中都含有六大默认成员函数&#xff0c;也就是说&#xff0c;即使这个类是个空类&#xff0c;里面什么都没有写&#xff0c;但是编译器依然会自动生成六个默认成员函数…...

每日英语学习(11)大英复习单词和翻译

2023.2.20 单词 1.contemplate 思考、沉思 2.spark 激起 3.venture 冒险 4.stunning 极好的 5.dictate 影响 6.diplomatic 外交的 7.vicious 恶性的 8.premier 首要的 9.endeavor 努力 10.bypass 绕过 11.handicaps 不利因素 12.vulnerable 脆弱的 13.temperament 气质、性格…...

x79主板M.2无法识别固态硬盘

问题描述: 这几天在装电脑&#xff0c;买了块M.2接口固态硬盘。装上去始终无法读取到硬盘&#xff0c;一开始以为是寨板Bios问题不支持M.2的设备。更新了最新的BIOS然后还是没有识别出来&#xff0c;然而将日常用的电脑PM510硬盘装上发现可以识别&#xff0c;而且日常用电脑也…...

配置Tomcat性能优化

配置Tomcat性能优化 &#x1f4d2;博客主页&#xff1a; 微笑的段嘉许博客主页 &#x1f4bb;微信公众号&#xff1a;微笑的段嘉许 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐留言&#x1f4dd; &#x1f4cc;本文由微笑的段嘉许原创&#xff01; &#x1f4…...

Hive3 安装方式详解,datagrid自定义驱动连接hive

1 Hive的安装方式 hive的安装一共有三种方式:内嵌模式、本地模式、远程模式。 元数据服务(metastore&#xff09;作用是&#xff1a;客户端连接metastore服务&#xff0c;metastore再去连接MySQL数据库来存取元数据。有了metastore服务&#xff0c;就可以有多个客户端同时连接…...

约束优化:约束优化的三种序列无约束优化方法(罚函数法)

文章目录约束优化&#xff1a;约束优化的三种序列无约束优化方法&#xff08;罚函数法&#xff09;外点罚函数法L2-罚函数法&#xff1a;非精确算法对于等式约束对于不等式约束L1-罚函数法&#xff1a;精确算法内点罚函数法&#xff1a;障碍函数法参考文献约束优化&#xff1a;…...

你真的会做APP UI自动化测试吗?我敢打赌百分之九十的人都不知道这个思路

目录 前言 一&#xff0c;开发语言选择 二&#xff0c;UI测试框架选择 1&#xff0c;Appium 2&#xff0c;Airtest 3&#xff0c;选择框架 三&#xff0c;单元测试框架选择 四&#xff0c;测试环境搭建 1&#xff0c;测试电脑选择 2&#xff0c;测试手机选择 3&#…...

GIT:【基础三】Git工作核心原理

目录 一、Git本地四个工作区域 二、Git提交文件流程 一、Git本地四个工作区域 工作目录(Working Directory)&#xff1a;电脑上存放开发代码的地方。暂存区(Stage/Index)&#xff1a;用于l临时存放改动的文件&#xff0c;本质上只是一个文件&#xff0c;保存即将提交到文件列…...

【1.12 golang中的指针】

1. 指针 区别于C/C中的指针&#xff0c;Go语言中的指针不能进行偏移和运算&#xff0c;是安全指针。 要搞明白Go语言中的指针需要先知道3个概念&#xff1a;指针地址、指针类型和指针取值。 1.1. Go语言中的指针 Go语言中的函数传参都是值拷贝&#xff0c;当我们想要修改某…...

十五.程序环境和预处理

文章目录一.程序翻译环境和执行环境1.ANSI C 标准2.程序的翻译环境和执行环境二.程序编译和链接1.翻译环境2.编译本身的几个阶段3.运行环境三.预处理1.预定义符号2.#define&#xff08;1&#xff09;#define定义标识符&#xff08;2&#xff09;#define定义宏&#xff08;3&…...

高并发系统设计之负载均衡

本文已收录至Github&#xff0c;推荐阅读 &#x1f449; Java随想录 文章目录DNS负载均衡Nginx负载均衡负载均衡算法负载均衡配置超时配置被动健康检查与主动健康检查LVS/F5Nginx当我们的应用单实例不能支撑用户请求时&#xff0c;此时就需要扩容&#xff0c;从一台服务器扩容到…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)

引言 在嵌入式系统中&#xff0c;用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例&#xff0c;介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单&#xff0c;执行相应操作&#xff0c;并提供平滑的滚动动画效果。 本文设计了一个…...