11-2 关联容器概述
目录
11.2.1 定义关联容器
//声明空容器
map<string, size_t> word_count;
//列表初始化
set<string> exclude = {"the","and","or"};
map<string, string> authors = { {"John","James"},
{"Asten","Jane"},
{"Dikens","Charles"}};
初始化multimap或multiset#
int main(){
//定义一个有20个元素的vector,保存0到9每个整数的两个拷贝
vector<int> ivec;
for (vector<int>::size_type i = 0; i != 10; ++i){
ivec.push_back (i) ;
ivec.push_back(i); //每个数重复保存一次
}
//iset包含来自ivec的不重复的元素;miset包含所有20个元素
set<int> iset(ivec.cbegin(), ivec.cend()) ;
multiset<int> miset(ivec.cbegin(), ivec.cend());
cout<< ivec.size () << endl; //打印出20
cout<< iset.size ( ) <<endl; //打印出 10
cout << miset.size () <<endl;//打印出20
return 0;
}
11.2.2 关键字类型的要求
对于有序容器map,multimap,set,multiset,关键字类型必须定义元素比较的方法
传递给排序算法的可调用对象(参见10.3.1节,第344页)必须满足与关联容器中关键字一样的类型要求
有序容器的关键字类型#
可以向一个算法提供我们自己定义的比较操作(参见10.3节,第344页),与之类似,也可以提供自己定义的操作来代替关键字上的<运算符。
所提供的操作必须在关键字类型上定义一个严格弱序(strict weak ordering)。可以将严格弱序看作“小于等于”,虽然实际定义的操作可能是一个复杂的函数。无论我们怎样定义比较函数,它必须具备如下基本性质:
- 两个关键字不能同时“小于等于”对方;如果k1“小于等于”k2,那么k2绝不能“小于等于”k1。
- 如果 k1“小于等于”k2,且k2“小于等于”k3,那么k1必须“小于等于”k3。
- 如果存在两个关键字,任何一个都不“小于等于”另一个,那么我们称这两个关键字是“等价”的。如果k1“等价于”k2,且k2“等价于”k3,那么k1必须“等价于”k3。
在实际编程中,我们考虑的是一个类型是否定义了“行为正常”的<运算符,只要定义了,它就可以用作关键字类型
使用关键字类型的比较函数#
假设一个类类型Sale_data未定义‘<’,此时我们可以自己定义一个比较函数传给map,来创建一个Sale_data的map【否则无法创建】
//依照isbn排序
bool compareIsbn(const Sale_data &lhs, const Sale_data &rhs){
return lhs.isbn()<rhs.isbn();
}
创建Sale_data的map:
//bookstore中多条记录可以有相同的isbn
//bookstore中的元素以isbn顺序进行排序
multiset<Sale_data, decltype(compareIsbn)*>
bookstore(compareIsbn);
模板接受两个参数,一个指定元素类型,一个函数指针
声明时传入函数指针compareIsbn
注:和数组名表示一个指针类似,函数名就代表函数指针
11.2.3 pair类型
声明和初始化#
定义在头文件utility
中
有两个数据成员first和second,必须提供两个类型参数
pair<string, string> anon; //保存两个string
pair<string, size_t> word_count; //一个string一个size_t
可以在声明时直接初始化first和second成员:
pair<int, int> i_to_i{1,2};
cout<<i_to_i.first<<" "<<i_to_i.second<<endl;
//输出:1 2
支持的操作#
创建pair对象的函数#
函数可以返回pair对象
pair<string, int> process(vector<string> &v){
if(!v.empty())
return
//构造一个pair并返回其拷贝
pair<string, int>(v.back(), v.back().size());
else
//构造空pair并返回其拷贝
return pair<string, int>();
}
除了直接定义外,还可以用make_pair来生成pair对象:
if(!v.empty())
return make_pair(v.back(), v.back().size());
新标准允许在返回pair时直接进行列表初始化:
if(!v.empty())
return {v.back(), v.back().size()};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用