重拾C++ 关联容器

来源:互联网 发布:防蹭网软件怎么用 编辑:程序博客网 时间:2024/05/02 02:15
关联容器
set:
C++中的set与Python中的不同在于前者是有序集,后者是无序集(这与Python中利用hash实现有很大
关系),前者考虑是红黑树。故(C++)set的特点应该是实现优先队列。(用重载比较运算符
的类充当元素)


简单的检测可以用如下的例子:


class Base{public:        string name;        Base(const string &s){name = s;}        bool operator < (const Base&b0)const        {                return this->name.size() < b0.name.size();        }};




set<Base>sb0{Base("jack"), Base("zz")};
for_each(sb0.begin(), sb0.end(), [](const Base&b){cout << b.name << " ";});
cout << endl;


有序的关联容器类必须是定义"<"的。
这里值得注意的是定义的“<”运算符,需要加修饰const,虽然感觉后置的const没什么用,
但不加会编译出错。(0*)


set multi_set在C++ 标准中还规定,其可使用谓词来指定序,但并非每个编译器都支持。


pair:
pair的初始化函数有一个“bug”, 其既兼容“合理”的列表初始化
(pair<type0, type1>{first, second}),
又兼容“不合理”的显示构造初始化(pair<type0, type1>(first, second)),
仅仅是构造函数进行多重重载的“示好”而已。


pair的比较对于first second遵循字典序。
使用make_pair进行pair初始化的好处在于,利用auto保存变量时,不需要显式进行
模板实例化。


对于不同关联容器的模板数据类型的调用,有关的是key_type value_type mapped_type
最后一个仅对map有,set同时有相同的key_type value_type
由前面提到的标准库set基于树的实现知道这并不是平凡的。
比较有用的是key_type及 mapped_type


这里map的value_type 为pair<const key_type, mapped_type>是其为容器的value_type,
而非元素的value_type,这与其它容器(顺序容器)中value_type是相一致的。
与Python的情况不同。


关联容器的元素类型都是const:set的元素时const, map的键是const。
要牢记这个只读特性。


map insert方法返回的是插入后的迭代器,指向map value_type元素,即pair类型。
insert等关联容器操作也可以支持两个参数(第一个隐含地提醒插入的位置),
可能有一些性能的影响。
erase操作基本与顺序容器erase操作一样,返回值的特性也是相同的。(被删除后的
后迭代器),接受的除了迭代器及其范围外,还可以根据键删除值。


在库typeinfo中定义了关键字typeid,其类似于Python中的type关键字,可以用来比较
对象的类型。提供了== !=运算符。这一点有了一些脚本语言的特点。
虽然typeid给予了使用者判断类型的工具,但对于C++的编译特性来说,助力是有限的,
很难简单而有意义地使用该特性。
如简单地按照不同类型进行输出是很困难地,下面是一个不能执行的例子:
Ex:
 
       if (typeid(mis1) == typeid(map<int, string>{{100, "s"}}))        {                for_each(mis1.begin(), mis1.end(), [](const pair<int, string>& element){cout << element.first << " " << element.second;});        }        else        {                for_each(mis1.begin(), mis1.end(), [](const int & element){cout << element << " ";});        }


这里mis1是一个map<int, string>或其它类型。
不能执行的原因是类型编译出错(else中的int类型),这与Python这样的动态语言是不同的。


对于关联容器进行访问的方法,对于map的下标操作,可以使用[]或.at()来实现(后者除了
在键不存在的时候抛出异常外,还能防止在键不存在时访问导致容器对此元素进行默认初始化
的“副作用”),
关联容器可以使用find返回迭代器,count用于计数。考虑到优先队列性质,还可以使用
lower_bound upper_bound equal_range返回迭代器或迭代器pair。


这里值得注意的一点是,multimap的序,是键的序,而非pair的序,后者是有字典序比较
特征的,在multimap当键的序相同时在insert时插入的元素的顺序与容器后来元素的顺序是
一致的。


无序容器部分略过。















0 0