关联容器

来源:互联网 发布:mac彩妆面试真的难 编辑:程序博客网 时间:2024/05/16 07:55
关联容器类型map关联数组;元素通过键来存储和读取set大小可变的集合,支持通过键实现的快速读取multimap支持同一个键多次出现的map类型multiset支持同一个键多次出现的set类型关联容器和顺序容器的本质区别在于:关联容器通过键(Key)存储和读取元素,而顺序容器则通过元素在容器中的位置顺序存储和访问元素。一般来说,如果希望有效存储不同值的集合,那么使用set容器比较合适,而map容器则更适用于需要存储每个键所关联的值的情况。在做某种文本处理时,可使用set保存要忽略的单词,而字典则是map的一种很好的应用:单词本身是键,而他的解释说明则是值。set和map类型的对象所包含的元素都具有不同的键,不允许为同一个键添加第二个元素。如果一个键必须对应多个实例,则需要使用multimap或multiset类型,这两种类型允许多个元素拥有相同的键。map类型map是键-值对的集合。map类型通常可理解为关联数组:可使用键作为下标来获取一个值,正如内置数组类型一样。而关联的本质在于元素的值与某个特定的键相关联,而并非通过元素在数组中的位置来获取。1.map对象的定义要使用map对象,必须包含其头文件。在定义map对象时,必须分别指明键和值的类型:map<string, int> word_count;这个语句定义了一个名为word_count的map对象,由string类型的键索引,关联的值则为int型。map<k, v> m;创建一个名为m的空map对象,其键和值的类型分别为k和vmap<k, v> m(m2);创建m2的副本m,m与m2必须有相同的键类型和值类型map<k, v> m(b, e);创建map类型的对象m,存储迭代器b和b标记的范围内所有元素的副本。元素的类型必须能够转换为pair<const k, v>2.键类型的约束在使用关联容器时,它的键不但有一个类型,而且还有一个相关的比较函数。默认情况下,标准库使用键类型定义的<操作符来实现键的比较。在实际应用中,键类型必须定义<操作符,而且该操作符应能“正确的工作”,这一点很重要。3.map类定义的类型map<k,v>::key_type在map容器中,用作索引的键的类型map<k,v>::mapped_type在map容器中,用作关联的值的类型map<k,v>::value_type一个pair类型,它的first元素具有const map<k,v>::key_type类型,而second元素则为map<k,v>::mapped_type类型4.给map添加元素该项工作可使用insert成员实现,或者,先用下标操作符获取元素,然后给获取的元素赋值。使用下标访问map对象:如下编写程序时:map<string, int> word_count;word_count["Anna"] = 1;将发生以下事情:(1)在word_count中查找键为Anna的元素,没有找到。(2)将一个新的键-值对插入到word_count中,它的键是const string类型的对象,保存Anna。而它的值则采用值初始化,这就意味着在本例中值为0.(3)将这个新的键-值对插入到word_count中。(4)读取新插入的元素,并将它的值赋为1.使用下标访问map与使用下标访问数组或vector的行为截然不同,用下标访问不存在的元素将导致在map容器中添加一个新的元素,它的键即为该下标值。5.map::insert的使用map容器提供的insert操作m.insert(e);m.insert(beg, end);m.insert(iter, e);直接使用insert成员,其语法更紧凑:word_count.insert(map<string, int>::value_type("Anna", 1));这个insert函数版本的实参map<string, int>::value_type("Anna", 1)是一个新创建的pair对象。传递给insert的实参相当笨拙,可用两种方法简化:使用make_pair:word_count.insert(make_pair("Anna", 1));或使用typedef:typedef map<string, int>::value_type valType;word_count.insert(valType("Anna", 1));这两种方法都是调用变得简单,提高了程序的可读性。5.1检测insert的返回值带有一个键-值形参的insert版本将返回一个值:包含一个迭代器和一个bool值的pair对象,其中迭代器指向map中具有相应键的元素,而bool值则表示是否插入了该元素。5.2语法展开pair<map<string, int>::iterator, bool> ret = word_cout.insert(make_pair(word, 1));首先,应该很容易看出我们定义的是一个pair对象,它的second成员为bool类型,而它的first成员则比较难理解,这是map<string, int>容器所定义的迭代器类型。下面对这个表达式一步步的展开解释:ret存储insert函数返回的pair对象。该pair对象的first成员是一个map迭代器,指向插入的键。ret.first->second对该迭代器进行解引用,获得一个value_type类型的对象。这个对象同样是pair类型的,它的second成员即为我们所添加的元素的值的部分。++ret.first->second实现该值的自增运算。归结起来,这个自增语句获取指向按word索引的元素的迭代器,并将该元素的值加1.6.查找并读取map中的元素下标操作符给出了读取一个值的最简单方法:map<string, int> word_count;int occurs = word_count["foobar"];但是,使用下标存在一个很危险的副作用:如果该键不在map容器中,那么下标操作会插入一个具有改键的新元素。然而,大多数情况下,我们只想知道某元素是否存在,而当该元素不存在时,并不想做插入运算。对于这种情况,map提供了两个操作:count和find,用于检查某个键是否存在而不会插入该键。m.count(k); 返回m中k的出现次数m.find(k);如果m容器中存在按k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器。6.1对于map对象,count成员的返回值只能是0或1.map容器只允许一个键对于一个示例,所以count可有效的表明一个键是否存在。int occurs = 0;if (word_count.count("foobar"))occurs = word_count["foobar"];6.2读取元素而又不插入该元素find操作返回指向元素的迭代器,如果元素不存在,则返回end迭代器:int occurs = 0;map<string, int>::interator it = word_count.find("foobar");if (it != word_count.end())occurs = it->second;7.从map对象中删除元素m.erase(k);删除m中键为k的元素。返回size_type类型的值,表示删除的元素个数m.erase(p);从m中删除迭代器p所指向的元素,p必须指向m中确实存在的元素,而且不能等于m.end().返回类型void类型。m.erase(b, e);从m中删除一段范围内的元素,该范围由迭代器对b和e标记。8.map对象的迭代器遍历与其他容器一样,map同样提供begin和end运算,以生成用于遍历整个容器的迭代器。9.set容器支持大部分的map操作,两种例外:set不支持下标操作符,而且没有定义mapped_type类型。在set容器中,value_type不是pair类型,而且与key_type相同的类型。10.multimap和multiset类型这两种类型支持一个键对于多个实例,其所支持的操作分别与map和set的操作相同,只有一个例外multimap不支持下标运算。因为在这类容器中,某个键可能对应多个值。10.1元素的添加和删除带有一个键参数的erase版本将删除拥有该键的所有元素,并返回删除元素的个数。而带有一个或一对迭代器参数的版本只删除指定的元素,并返回void类型。10.2在multimap和multiset中查找元素关联容器map和set的元素是顺序存储的,而multimap和multiset也一样,同一个键所关联的元素必然相邻存放。m.lower_bound(k);返回一个迭代器,指向键不大于k的第一个元素。m.upper_bound(k);返回一个迭代器,指向键大于k的第一元素。m.equal_range(k);返回一个迭代器的pair对象,它的first成员等价于m.lower_bound(k).而second成员则等价于m.upper_boook(k).在同一个键上调用lower_bound和upper_bound,将产生一个迭代器范围,指示出该键所关联的所有元素。

0 0
原创粉丝点击