5. 关联容器
(1)关联容器的特点
(1)容器需要存放对象和key值,key值与对象之间是一种映射关系。
(2)每个对象被存入到关联容器中时,会对key进行排序,进过比较后找到合适的
位置后存放。因此key的数据类型需要提供排序方法,可以通过提供orerator<()
或者Compare这两个函数进行比较。
(3)map只支持双向迭代器,因此不支持随机访问,虽然map支持[key]的方式访问对象,
但是这并不是随机访问。
(2)关联容器分类
(1)map类:不允许key重复
(2)multimap类:map的特例,允许key重复
(3)set类:对象本身就是key值,不允许重复
(4)multiset类:set的特例,允许重复
(3)map的模板
前面的vector和list模板原本需要两个模板参数,但是实际上我们基本都只
指定第一个模板参数。
map类的模板参数比较多,总共有四个模板参数,map的类模板定义如下:
template < class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key,T> > > class map;
(1)模板参数1:key值的类型
(2)模板参数2:key对应数据的类型
(3)模板参数3:用于排序时进行比较的函数对象类型
(4)模板参数4:用于在map中分配存储空间的函数类型
一般情况下,我们只需要指定前两个模板参数即可。
(4)定义一个map
(1)定义一个空的map
std::map<std::string, Student> stumap;
调用map的默认构造函数,定义一个空的map对象,第一个模板类型参数
string表示key值的类型为string,第二个Student表示需要存储的对象
是Student类型。
但是实际上key和存放的对象的类型可以使任何类型。
(2)定义一个map,利用另一个map的袁元素进行初始化
std::map<std::string, Student> stumap<iter1, iter2>;
使用另一个map的[iter1, iter2)之间的元素初始化map。
(4)如何构建键值对
将key和对应对象构建成为键值对的方法有三个:
(1)std::make_pair("123", stu)
(2)std::map<string, Student> :: value_type("111",stu)
(3)std::pair<string, Student>("222",stu)
这三个函数在调用insert()插入新的键值对时很重要,比如:
enumMap.insert(map<int,CString> :: value_type("111", stu))
enumMap.insert(pair<int,string>("222", stu));
(5)访问map
(1)使用[]
(1)作为右值:Student stu = stumap["111"];
如果"111"对应的对象比更不存在,便会使用Student的默认构造函数创
建一个Student对象。实际上只有确保"111"对应的对象存在才有意义。
(2)作为左值:Stumap["222"] = stu;
作为左值时,如果"222"对应的键值对不存在,就创建一个新的键值对,
然后将内容赋值为stu,利用这样的方式可以实现插入新键值对的操作,
当然还可以使用insert()成员函数实现插入操作。
不管是作为左值还是右值,提前确定键值对是否存在非常关键,所以我
们可以使用find成员函数先查找该key值对应的对象是否存在,存在就返
回指向该位置的迭代器,然后使用该迭代器进行操作,否者就不操作。
(2)迭代器遍历
(1)使用的是双向迭代器,不支持随机访问
(2)正向迭代器需要用到begin()和end()函数
(3)逆向迭代器rbegin()函数和rend()函数。
(4)通过iter->second成员和iter->first成员就可以获取数据和键值key,
second成员中存放的是数据,first存放的是键值。
这里只能使用->,不能使用*和.操作。
(3)例子
#include <iostream>
#include <algorithm>
#include<iterator>
#include<sstream>
#include<stdlib.h>
#include<stdio.h>
#include <map>
using namespace std;
class Student {
public:
Student(const string name=" "):name(name) { }
string getname() const { return name; }
private:
string name;
};
/* 使用迭代器遍历map */
template <class Iter> void show_map(Iter first, Iter last) {
for( ;first!=last; first++) {
/* 使用first访问键值,使用second访问对象,注意,通过迭代器访问到的
只是键值对,必须使用->访问first和second才能访问到具体的键值和对应数据,
由于存储的对象是地址,访问Student的name时,必须再次使用-> */
cout << first->first<<" "<< ((first)->second)->getname()<<endl;
}
}
int main(void)
{
/* 定义一个空的map */
std::map<string, Student*> map1;
cout<< "使用[]做为左值插入新元素" <<endl;
map1["111"] = new Student("zhangsan");
map1["222"] = new Student("wangwu");
map1["333"] = new Student("lisi");
map1["333"] = new Student("wwwwww");
map1["444"] = new Student("zhaosi");
/* 使用正向迭代起遍历 */
cout<< "显示map1中的元素" <<endl;
show_map(map1.begin(), map1.end());
/* 使用map1中的内容去初始化map2 */
cout<< "\n使用map1中[++map1.begin(), --map1.end())之间的元素初始化map2" <<endl;
std::map<string, Student*> map2(++map1.begin(), --map1.end());
/* 使用逆向迭代起遍历 */
cout<< "显示map2中的元素" <<endl;
show_map(map2.rbegin(), map2.rend());
return 0;
}
运行结果:
使用[]做为左值插入新元素
显示map1中的元素
111 zhangsan
222 wangwu
333 wwwwww
444 zhaosi
使用map1中[++map1.begin(), --map1.end())之间的元素初始化map2
显示map2中的元素
333 lisi
222 wangwu
例子分析:
map中不允许出现重复的key,如果出现,最后出现的key的对象将会覆盖
之前同名key对应的对象,比如例子中有两个"333"的key值,但是map只存放
最后一个"333"对用的对象。
(6)使用map的成员函数实现插入和删除元素等操作
(1)涉及成员函数
(1)clear() 删除所有元素
(2)count() 返回指定元素出现的次数
(3)empty() 如果map为空则返回true
(4)erase() 删除一个元素
void erase ( iterator position );
size_type erase ( const key_type& x );
void erase ( iterator first, iterator last );
(5)find() 查找一个元素
iterator find ( const key_type& x );
const_iterator find ( const key_type& x ) const;
(6)insert() 插入元素
pair<iterator,bool> insert ( const value_type& x );
iterator insert ( iterator position, const value_type& x );
template <class InputIterator>
void insert ( InputIterator first, InputIterator last );
(7)max_size() 返回可以容纳的最大元素个数
(8)size() 返回map中元素的个数
(9)swap() 交换两个map
(2)举例
例子1:(1)—(5)函数举例
#include <iostream>
#include <algorithm>
#include<iterator>
#include<sstream>
#include<stdlib.h>
#include<stdio.h>
#include <map>
using namespace std;
class Student {
public:
Student(const string name=" "):name(name) { }
string getname() const { return name; }
private:
string name;
};
/* 使用迭代器便利map */
template <class Iter> void show_map(Iter first, Iter last) {
for( ;first!=last; first++) {
cout << first->first<<" "<< ((first)->second)->getname()<<endl;
}
}
int main(void)
{
/* 定义一个空的map */
std::map<string, Student*> map1;
cout<< "使用[]做为左值插入新元素" <<endl;
map1["111"] = new Student("zhangs");
map1["222"] = new Student("wangwu");
map1["333"] = new Student("lisssi");
map1["444"] = new Student("dsfsfd");
map1["555"] = new Student("werrre");
map1["666"] = new Student("qwewss");
map1["777"] = new Student("sdgfgf");
map1["888"] = new Student("zzcvvv");
map1["999"] = new Student("cxbnhh");
map1["000"] = new Student("zqwerz");
if(map1.empty()) cout <<"\nmap1为空"<<endl;
else cout <<"\nmap1不为空"<<endl;
cout<<"\n333键值出现的次数:"<<map1.count("333")<<endl;
cout<< "使用erase删除指定元素" <<endl;
map1.erase(++map1.begin());
map1.erase("222");
map1.erase(++map1.begin(), --map1.end());
cout<< "\nmap1剩余的元素为" <<endl;
show_map(map1.begin(), map1.end());
cout<< "\n查在map1中查找“333”键值对" <<endl;
if(map1.find("333") != map1.end()) {
cout <<"\n333对应的对象找到:" <<(map1["333"])->getname()<<endl;
}
return 0;
}
例子2:(6)—(9)函数举例
#include <iostream>
#include <algorithm>
#include<iterator>
#include<sstream>
#include<stdlib.h>
#include<stdio.h>
#include <map>
using namespace std;
class Student {
public:
Student(const string name=" "):name(name) { }
string getname() const { return name; }
private:
string name;
};
/* 使用迭代器便利map */
template <class Iter> void show_map(Iter first, Iter last) {
for( ;first!=last; first++) {
cout << first->first<<" "<< ((first)->second)->getname()<<endl;
}
}
int main(void)
{
/* 定义一个空的map */
std::map<string, Student*> map1;
std::map<string, Student*> map2;
cout<< "使用[]做为左值插入新元素" <<endl;
map1["333"] = new Student("lisssi");
map1["111"] = new Student("zhangs");
map1["555"] = new Student("werrre");
map1["777"] = new Student("sdgfgf");
map1["222"] = new Student("wangwu");
map1["444"] = new Student("dsfsfd");
map1["666"] = new Student("qwewss");
map1["888"] = new Student("zzcvvv");
map1["999"] = new Student("cxbnhh");
map1["000"] = new Student("zqwerz");
cout <<"\n交换map1和map2"<<endl;
map1.swap(map2);
cout <<"显示交换后map1的内容"<<endl;
show_map(map1.begin(), map1.end());
cout <<"\n显示交换后map2的内容"<<endl;
show_map(map2.begin(), map2.end());
cout <<"\n使用insert函数向map1中插入新元素"<<endl;
map1.insert(make_pair("123", new Student("zzzzzzz")));
map1.insert(make_pair("234", new Student("bbbbbbb")));
map1.insert(pair<string, Student*>("345", new Student("bbbbbbb")));
map1.insert(map<string, Student*>::value_type("456", new Student("ccccccc")));
map1.insert(map<string, Student*>::value_type("567", new Student("ddddddd")));
show_map(map1.begin(), map1.end());
cout <<"\nmap1中可以容纳的最大元素个数:"<< map1.max_size()<<endl;
cout <<"\nmap1中实际元素个数:"<< map1.size()<<endl;
return 0;
}
运行结果:
使用[]做为左值插入新元素
交换map1和map2
显示交换后map1的内容
显示交换后map2的内容
000 zqwerz
111 zhangs
222 wangwu
333 lisssi
444 dsfsfd
555 werrre
666 qwewss
777 sdgfgf
888 zzcvvv
999 cxbnhh
使用insert函数向map1中插入新元素
123 zzzzzzz
234 bbbbbbb
345 bbbbbbb
456 ccccccc
567 ddddddd
map1中可以容纳的最大元素个数:178956970
map1中实际元素个数:5
例子分析:
从打印结果可以明显的看出,插入map时,会对key值进行自动排序,
主动排序使用的时map提供的默认比较函数。
(7)multimap
与map一样,操作的成员函数与map都一样,只是multimap允许出现键值对重复。
但是与map也有些其它不同。
(1)multimap不能使用[]
(2)find函数只返回指向重复key的第一个键值对的迭代器
例子:
#include <iostream>
#include <algorithm>
#include<iterator>
#include<sstream>
#include<stdlib.h>
#include<stdio.h>
#include <map>
using namespace std;
class Student {
public:
Student(const string name=" "):name(name) { }
string getname() const { return name; }
private:
string name;
};
/* 使用迭代器便利map */
template <class Iter> void show_map(Iter first, Iter last) {
for( ;first!=last; first++) {
cout << first->first<<" "<< ((first)->second)->getname()<<endl;
}
}
int main(void)
{
/* 定义一个空的map */
std::multimap<string, Student*> map1;
cout <<"\n使用insert函数向map1中插入新元素"<<endl;
map1.insert(make_pair("123", new Student("aaazzzzzzz")));
map1.insert(make_pair("123", new Student("zzzzzzz")));
map1.insert(make_pair("123", new Student("zzzzzzz")));
map1.insert(make_pair("234", new Student("bbbbbbb")));
map1.insert(pair<string, Student*>("345", new Student("bbbbbbb")));
map1.insert(map<string, Student*>::value_type("456", new Student("ccccccc")));
map1.insert(map<string, Student*>::value_type("567", new Student("ddddddd")));
show_map(map1.begin(), map1.end());
cout <<"\n查找123对应的对象:"<< map1.max_size()<<endl;
cout<<(map1.find("123")->second)->getname() << endl;
cout <<"\nmap1中可以容纳的最大元素个数:"<< map1.max_size()<<endl;
cout <<"\nmap1中实际元素个数:"<< map1.size()<<endl;
return 0;
}
运行结果:
使用insert函数向map1中插入新元素
123 aaazzzzzzz
123 zzzzzzz
123 zzzzzzz
234 bbbbbbb
345 bbbbbbb
456 ccccccc
567 ddddddd
查找123对应的对象:aaazzzzzzz
map1中可以容纳的最大元素个数:178956970
map1中实际元素个数:7
(8)函数类类型(函数对象)
(1)函数指针类型
讲函数类类型之前先回忆函数指针类型,函数指针类型的形式,
返回类型 (*)(形参类型列表);
比如:void *(*)(void *);
这就是我们之前讲的线程函数的函数类型,由于该类型比较复杂,因此
往往会使用typedef将其简化。
typedef void *(*ftype)(void *);
ftype fp =NULL;
通过ftype定义的fp就是我们希望得到的函数指针变量。
(2)函数类类型与函数指针类型的区别
使用函数指针类型定义的变量只是用于存储函数地址,必须明白,函数指针变量
并不是函数本身,该变量只是指向了某个函数。
换句话说,不能使用函数指针类型定义一个函数,只能用它定义一个存放函数
地址的函数指针变量,至于该函数指针变量指向的函数,我们需要另外定义。
但是c++中扩展了函数类类型,有了这个类型后,就可以实例化一个函数
对象,也就是可以像定义一个类对象一样定义一个函数,使用非常的方便。
(3)函数类类型如何定义和使用
(1)函数类类型
使用函数类类型,我们可以像实例化一个普通对象一样去实例化一个函数对象,
在实例化的时候,这个函数对象包含了函数的实现,可以将函数对象直接作为
参数进行传递时非常的方便。
如果没有函数对象,那么我们就必须使用函数指针实现,实际上如果没有函数
对象,c++并不会因此而少了什么,完全可以使用函数指针替代,不过在c++在STL
模板库中大量的使用到了函数对象。
有了函数类类型,我们就可以根据需求实例化任何我们需要的函数对象。
(2)函数类类型的实现原理
声明一个类型(class/struct),在类型中对()操作符进行重载,对()重载了
的类型就被认为是函数类类型。
使用该函数类类型就可以实例化函数对象,实例化对象时就实现了一个函数,
对象名字可以被认为就是函数的的名字。
可以使用结构体实现函数类类型,只是在使用结构体时,它成员默认是public的,
请自行测试使用结构体方式实现的函数类类型。
(4)将函数作为参数进行传递时
(1)传统方式:传递函数地址
(2)新的方法:传递函数对象
例子:
#include <iostream>
#include <algorithm>
#include<iterator>
#include<sstream>
#include<stdlib.h>
#include<stdio.h>
#include <map>
using namespace std;
class Student {
public:
Student(const string name=" "):name(name) { }
string getname() const { return name; }
private:
string name;
}
/* 声明一个函数类类型,使用typedef为其定义一个别名 */
typedef class Funclass {
public:
void operator()(const Student &stu) {
cout<<stu.getname() <<endl;
}
}Funtype;
/* 定义一个普通函数,使用函数对象进行传参 */
void display(Funtype func1, Funtype &func2, Funtype *func3, const Student &stu){
cout << "通过函数对象调用实例化的函数" <<endl;
func1(stu);
cout << "\n通过函数对象引用调实例化的用函数" <<endl;
func2(stu);
cout << \n"通过函数对象指针调用实例化的函数" <<endl;
(*func3)(stu);
}
int main(void)
{
Student stu("zhangsan");
Funtype func;//定义一个函数对象
/* 将函数对象作为参数进行传递
*参数1:传递对象
*参数2:传递对象引用
*参数3:传递对象地址 */
display(func, func, &func, stu);
return 0;
}
运行结果:
通过函数对象调用函数
zhangsan
通过函数对象引用调用函数
zhangsan
通过函数对象指针调用函数
zhangsan
(2)函数类类型模板
继续上面的例子,将上面例子中的函数类类型改为函数类模板。
#include <algorithm>
#include<iterator>
#include<sstream>
#include<stdlib.h>
#include<stdio.h>
#include <map>
using namespace std;
class Student {
public:
Student(const string name=" "):name(name) { }
string getname() const { return name; }
private:
string name;
};
/* 声明一个函数类模板,使用typedef为其定义一个别名 */
template<class T> class Funclass {
public:
void operator()(const T &stu) {
cout<<stu.getname() <<endl;
}
};
/* 定义一个普通函数,使用函数对象进行传参 */
void display(Funclass<Student> func1, Funclass<Student> &func2, Funclass<Student> *func3, const Student &stu){
cout << "通过函数对象调用实例化的函数" <<endl;
func1(stu);
cout << "\n通过函数对象引用调实例化的用函数" <<endl;
func2(stu);
cout << "\n通过函数对象指针调用实例化的函数" <<endl;
(*func3)(stu);
}
int main(void)
{
Student stu("zhangsan");
Funclass<Student> func;//定义一个函数对象
/* 将函数对象作为参数进行传递
*参数1:传递对象
*参数2:传递对象引用
*参数3:传递对象地址 */
display(func, func, &func, stu);
return 0;
}
运行结果:
通过函数对象调用实例化的函数
zhangsan
通过函数对象引用调实例化的用函数
zhangsan
通过函数对象指针调用实例化的函数
zhangsan
例子分析:
例子并没有做太大的改动,只是将函数类类型改成了函数类模板。
(3)给map自定义比较函数
(1)给基本类型的key定义比较函数
前面讲到,向map中插入数据时,map会自动调用默认的比较函数进行排序
(默认的是升序排序)。
但是map中的排序实在插入的时候进行的,目的是为插入的元素找到一个合
适的位置,排序只在插入元素时进行,之后不能单独对map进行调用sort函
数进行排序。
但是map只对key为基本类型时,实现了默认的升序排序,如果希望对基本
类型实现降序排序,或者想对非基本类型的key实现自定义类型排序,需要
自己实现比较函数。
如果比较函数返回true,小的在前,大的在后,这里的大小概念只是逻辑
上的,不是数据的真实大小,我们完全可以定义数值大的为小,数值小的
为大。
通过map模板的第三个模板参数给map指定函数类类型或者函数类模板后,
map会用它实例化一个比较函数。
例子:对map中string类型key值进行降序排序
#include <iostream>
#include <algorithm>
#include<iterator>
#include<sstream>
#include<stdlib.h>
#include<stdio.h>
#include <map>
using namespace std;
class Student {
public:
Student(const string name=" "):name(name) { }
string getname() const { return name; }
private:
string name;
};
/* 使用迭代器便利map */
template <class Iter> void show_map(Iter first, Iter last) {
for( ;first!=last; first++) {
cout << first->first<<" "<< ((first)->second)->getname()<<endl;
}
}
/* 声明一个函数类模板,使用typedef为其定义一个别名 */
template<class T> class Funclass {
public:
bool operator()(const T &op1, const T &op2) {
return op1 > op2;//按照从大到小比较
}
};
int main(void)
{
std::map<string, Student *> map1;
/* 利用map的第三个模板参数指定用于比较函数的类模板,
* map会使用该函数类模板自动实例化一个比较函数,
* 如果该比较函数返回 */
std::map<string, Student *, Funclass<string> > map2;
map1["444"] = map2["444"] = new Student("mnjnkkl");
map1["222"] = map2["222"] = new Student("qqqqqqs");
map1["111"] = map2["111"] = new Student("ddsfass");
map1["888"] = map2["888"] = new Student("asdfdff");
map1["666"] = map2["666"] = new Student("eqwewqe");
map1["555"] = map2["555"] = new Student("sdfsfds");
cout<<"显示map1的内容"<<endl;
show_map(map1.begin(), map1.end());
cout<<"\n显示map2的内容"<<endl;
show_map(map2.begin(), map2.end());
return 0;
}
运行结果:
显示map1的内容
111 ddsfass
222 qqqqqqs
444 mnjnkkl
555 sdfsfds
666 eqwewqe
888 asdfdff
显示map2的内容
888 asdfdff
666 eqwewqe
555 sdfsfds
444 mnjnkkl
222 qqqqqqs
111 ddsfass
例子分析:
从运行的结果中很容易看出,如果不给map1指定比较函数类类型或者模板
的话,默认会提供升序排序的比较函数。
在给map2提供了降序排序的比较函数模板后,map2便进行降序排序,从打
印结果中很容易看出这一点。
(2)给map类类型的key自定义比较函数
如果map中键值对的key是类类型的话,必须给map指定自定义的比较函数类
类型或者模板,否则将无法通过编译。
例子:
#include <iostream>
#include <algorithm>
#include<iterator>
#include<sstream>
#include<stdlib.h>
#include<stdio.h>
#include <map>
using namespace std;
class Stukey{
public:
Stukey(int key=1):key(key) {}
int key;
};
class Student {
public:
Student(const string name=" "):name(name) { }
string getname() const { return name; }
private:
string name;
};
/* 使用迭代器便利map */
template <class Iter> void show_map(Iter first, Iter last) {
for( ;first!=last; first++) {
cout << (first->first).key<<" "<< ((first)->second)->getname()<<endl;
}
}
class Funclass {
public:
bool operator()(const Stukey &op1, const Stukey &op2) {
return op1.key > op2.key;//按照从大到小比较
}
};
int main(void)
{
/* 如果不给map1和map2指定自定义的比较函数类
* 类行或者模板,将无法通过编译 */
std::map<Stukey, Student *, Funclass> map1;
/* 利用map的第三个模板参数指定比较函数类模板,
* map会使用该函数类模板自动实例化一个比较函数 */
std::map<Stukey, Student *, Funclass> map2;
map1[Stukey(444)] = map2[Stukey(444)] = new Student("mnjnkkl");
map1[Stukey(222)] = map2[Stukey(222)] = new Student("qqqqqqs");
map1[Stukey(111)] = map2[Stukey(111)] = new Student("ddsfass");
map1[Stukey(888)] = map2[Stukey(888)] = new Student("asdfdff");
map1[Stukey(666)] = map2[Stukey(666)] = new Student("eqwewqe");
map1[Stukey(555)] = map2[Stukey(555)] = new Student("sdfsfds");
cout<<"显示map1的内容"<<endl;
show_map(map1.begin(), map1.end());
cout<<"\n显示map2的内容"<<endl;
show_map(map2.begin(), map2.end());
return 0;
}
运行结果:
显示map1的内容
888 asdfdff
666 eqwewqe
555 sdfsfds
444 mnjnkkl
222 qqqqqqs
111 ddsfass
显示map2的内容
888 asdfdff
666 eqwewqe
555 sdfsfds
444 mnjnkkl
222 qqqqqqs
111 ddsfass
相关推荐
STL:关联容器 map
STL关联容器 set 映射容器(map):一对多映射,基于关键字快速查找,不允许重复值 map 的特点:每次放入两个数据 <key,value>,key 有序且不重复 1. 操作 1.1 初始化和查找 初始化map词典并访问 #include <iostream> #include <map> using namespace std; int main(){ // 映射dict目录/词典 map<string,string>
【STL八】关联容器
关联式容器存储的元素,都是一个一个的“键值对”。
学习STL的历程——关联容器
STL模板库包括了容器、算法、迭代器、仿函数、适配器、分配器。 主要谈谈容器 STL中的容器有序列容器和关联容器,容器适配器等 1)序列容器(以线性序列的方式存储元素,没对元素进行排序,元素的顺序和存储它们的顺序相同) 主要包括 vector string list deque 2)关联容器(存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高) 主要包括 set map multiset multimap 3)适配容器 就是由基本的容器适配(改造)出来的
STL:关联式容器 | set的基本使用 | map的基本使用
set和map的使用
别再手动找触点了!EPLAN线圈触点映像的3种显示方式与F键/Ctrl+B快捷键实战
本文详细解析EPLAN线圈触点映像的3种显示方式与F键/Ctrl+B快捷键实战技巧,帮助电气设计工程师提升图纸操作效率。通过精简编号、路径栏显示和元件旁可视化三种模式的应用场景对比,结合快捷键肌肉记忆训练法,实现触点快速定位与管理,大幅减少手动查找时间。
服务器卡死排查实战:从现象分类到根因定位的完整手册
服务器卡死是运维中最令人头疼的故障之一,从游戏圈吐槽的“土豆服务器”到生产环境中的Linux系统无响应、rsync复制挂起,本质都是系统或进程失去正常响应能力。其原理通常涉及CPU、内存、磁盘IO或网络资源耗尽,以及内核和驱动异常。掌握系统化的排查方法,能够帮助工程师快速定位根因、缩短故障时间,避免盲目重启。本文从资源、层级、场景等多维度分类,结合top、dmesg、strace等工具,梳理一套从现象确认、指标收集、日志分析到进程定位的实战排查流程,并覆盖常见高频场景与预防治理建议。无论你是运维新手还是老手
STL容器
C++之STL容器
DPARSF高级版 vs 基础版怎么选?没有T1数据也能做fMRI分析吗?
本文深度对比了DPARSF高级版与基础版在fMRI分析中的核心差异与适用场景,特别针对无T1数据的情况提供了实战解决方案。高级版依赖T1像实现高精度配准,适合需要精确解剖定位的研究;基础版则无需T1数据,适用于功能连接等相对空间要求不高的分析。文章还提供了版本选择决策树和常见问题解决方案,帮助研究者根据实际需求做出最优选择。
STL关联式容器介绍
在前文中介绍了STL的序列式容器;接下来对关联式容器(associative containers)进行学习及分享;根据“数据在容器中的排列”特性,容器可概分为序列式(Sequence)和关联式(associative)两种。标准的STL关联式容器分为set(集合)和map(映射表)两大类,以及两大类的衍生体multiset(多键集合)和multimap(多键映射表)。这些容器底层机制均以RB-tree(红黑树)完成。RB-tree也是独立容器,但并不开放给外界使用。
AIR780E二次开发点灯(LuatOS)
Air780E的LuatOS点灯教程,二次开发教程,可用于所有ec618平台,无需SDK
三. zemax光学设计流程+案例
文章目录zemax 基本操作:1. 建立光学基本模型2. 像质评价3. 优化(重点)4. 公差分析简单镜头设计 zemax 基本操作: 1. 建立光学基本模型 2. 像质评价 3. 优化(重点) 对系统设定的约束条件或目标值 统称为操作数。 操作数: 光学特性参数(焦距EFFL,近轴放大率PMAG,入瞳位置EMPP) 像差参数(球差SPHA,彗差COMA,像散ASTI) 边界条件(中心厚度值CTVA,边缘厚度值ETAV) 优化的主要步骤: 设置评价函数和优化操作数 一般小像差系统采用波像差 构建
4.关联式容器
关联式容器是指数据是键值对的格式。容器内部结构(可能是RB-tree或者hash-table)便依照其键值大小,以某种特定规则将这个元素放置于合适的位置,关联式容器没有所谓头尾(只有最大元素和最小元素);所以不会有所谓等行为的操作。
Linux系统中u-boot启动流程分析(详解)
代码部分,具体如下;
STL关联容器总结
一、关联式容器 STL 关联容器分为 set(集合)和 map(映射表)两大类,及其衍生体 multiset 和 multimap。这些容器的底层机制均以 RB-tree(红黑树)实现。RB-tree 也是一个独立容器,但并不开放使用。 SGI STL 还提供一个不在标准规格的关联式容器 hash_table(散列表),以及以 hash_table 为底层机制而完成的 hash_set散列...
【无人机编队】基于matlab虚拟leader无人机编队仿真【含Matlab源码 3279期】
虚拟leader无人机编队仿真 完整代码,包运行;可提供运行操作视频!适合小白!
使用SIMD思想进行memcpy的优化
arm64平台的memcpy的性能优化,相比C库提升30~40%,SIMD优化思路
【STL】关联容器的分类
本文的所有语句都经本人验证,均正确使用。由于本文涉及内容比较多,为了尽可能的讲详细些,会把各种例子附上,所以代码样例会比较多,也为了更好的布局,本系列将分开讲解,并且前期为了更加贴合实战需求,暂时只对一些常用的STL容器和基本功能进行讲解。为了使每篇文章具有一定的独立性,后续的文章大多数会将之前文章涉及的知识点中提取,并且在后续会将相应的例子补上。本文STL系列知识参考《C++语言程序涉及(第5版)》
温度PID控制PLC程序
温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值
STL 关联容器
std::unordered_set 是一个值的哈希表,值本身就是 key。其中,std::unordered_set、std::unordered_multiset、std::unordered_map。与顺序容器(如 std::vector、std::deque 等)不同,关联容器中的元素是通过。(C++11起)std::unordered_set、std::unordered_multiset。(C++11起)std::unordered_map、std::unordered_multimap。
jre9下载 jdk9
(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】
LinePhone3.2.7(android端最新版本) sip客户端
SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/
STL之三:关联容器
关联容器通过 键(Key) 高效存储和访问元素,它们的元素位置取决于键值,而非插入顺序。主要分为两类:1.无序关联容器,依赖于链式哈希表,增删查O(1)使用头文件:#include<unordered_set>、#include<unordered_map>set:集合 key map:映射表[key, value](键值对) unordered_set:单重集合 unordered_multiset:多重集合 unordered_map:单重映射表 unordered_multimap:
C++ STL(四)关联容器
std::multimap 是 C++ 标准模板库(STL)中的一个关联容器,用于存储键值对(key-value pairs),并按照键的顺序自动排序。std::multiset 的迭代器是一个双向迭代器,支持 ++ 和 -- 操作。std::set 的迭代器是一个双向迭代器,支持 ++ 和 -- 操作。与std::set 不同std::multiset允许存储重复的元素。std::set 的迭代器是一个双向迭代器,支持 ++ 和 -- 操作。:std::map 中的键是唯一的,不允许重复。
STL关联容器
关联容器有以下四种:set、multiset、map、multimap,关联容器内的元素是排序的,关联容器中的元素是从小到大排序(或按关键字从小到大排序)。关联容器带有模板参数 Key 和 Compare,这两个参数分别表示用来对内容进行排序的键类型和用于对键值进行比较的函数对象(被称为比较对象)。对于 set 和 multiset 容器,存储的键就是存储的值,都在头文件 set 中定义,两者区别...
【STL】——关联容器
1、关联容器 1.1基本概念 1.2关联容器都有的函数 2、set 详解 2.1基本操作 2.2特点 3、map详解 3.1基本操作 3.2特点 3.3关联容器在自定义类型下的使用
C++ STL之关联容器(C++ primer,P702)
关联容器将 value(值)与 key(键)关联在一起,并使用 key 来查找 value; 关联容器的优势是,提供元素的快速访问,也允许插入元素(但是不能固定位置插入) STL提供了四种有序关联容器:(底层都是树) set: 集合,key 唯一且 key 就是 value multiset: key 不唯一 map: key 与 value 不同,key 唯一 multimap: key 不唯...
【STL】关联容器基本功能
本文的所有语句都经本人验证,均正确使用。由于本文涉及内容比较多,为了尽可能的讲详细些,会把各种例子附上,所以代码样例会比较多,也为了更好的布局,本系列将分开讲解,并且前期为了更加贴合实战需求,暂时只对一些常用的STL容器和基本功能进行讲解。为了使每篇文章具有一定的独立性,后续的文章大多数会将之前文章涉及的知识点中提取,并且在后续会将相应的例子补上。本文STL系列知识参考《C++语言程序涉及(第5版)》
STL中关联容器
本文介绍STL中的关联容器的内容。 关联容器中的元素根据一些排序规则自动进行排序的。缺省的排序规则是关系运算符 因为关联容器中的元素是自动排序的,因此,当一个新的元素插入到容器中时,它插入到容器中适当的位置。一种方便和快速的实现该类数据结构的方式是使用二叉搜索树。实际上这就是关联容器实现的方式。因此,容器中每个元素有一个父节点(除了根结点),同时最多有两个孩子,对于各个元素,父节点的
STL关联容器的学习
STL关联容器的基础学习
609



被折叠的 条评论
为什么被折叠?



