11C第十一章习题解答.docx
《11C第十一章习题解答.docx》由会员分享,可在线阅读,更多相关《11C第十一章习题解答.docx(12页珍藏版)》请在冰豆网上搜索。
11C第十一章习题解答
第十一章标准模板库(STL)习题
一.大体概念与基础知识自测题
11.1填空题
11.1.1STL大量利用继承和虚函数是
(1)(填对或错)。
因为
(2)。
答案:
(1)错
(2)它利用的是模板技术,追求的是运行的效率,幸免了虚函数的开销
11.1.2有两种STL容器:
(1)和
(2)。
STL不用new和delete,而用(3)实现各类操纵内存分派和释放的方式。
答案:
(1)第一类容器
(2)近容器
(3)分派子(allocator)
11.1.3五种要紧迭代子类型为
(1)、
(2)、(3)、(4)和(5)。
STL算法用(6)间接操作容器元素。
sort算法要求用(7)迭代子。
答案:
(1)输入(InputIterator)
(2)输出(OutputIterator)
(3)正向(ForwardIterator)
(4)双向(BidirectionalIterator)
(5)随机访问(RandomAccessIterator)
(6)迭代子
(7)随机访问(RandomAccessIterator)
11.1.4三种STL容器适配器是
(1)、
(2)和(3)。
答案:
(1)stack(栈)
(2)queue(队列)
(3)priority_queue(优先级队列)
11.1.5成员函数end()取得容器
(1)的位置,而rend取得容器
(2)的位置。
算法通常返回(3)。
答案:
(1)最后一个元素的后继位置
(2)引用容器第一个元素的前导位置。
事实上这是该容器前后反转以后的end()
(3)迭代子
11.1.6适配器是
(1),它依附于一个
(2)容器上,它没有自己的(3)函数和(4)函数,而借用其实现类的对应函数。
答案:
(1)不独立的
(2)顺序
(3)构造函数
(4)析构函数
11.1.7返回布尔值的函数对象称为
(1),默许的是
(2)操作符。
答案:
(1)谓词(predicate)
(2)小于比较操作符“<”
11.1.8C++标准库中给出的泛型算法包括
(1)种算法。
要紧包括以下几类:
(2)、(3)、(4),每一类都有十种以上算法。
答案:
(1)70余
(2)查找算法
(3)排序(sorting)和通用整序(ordering)算法
(4)删除和代替算法
11.2简答题
11.2.1简述STL中迭代子与C++指针的关系与异同点。
答:
迭代子包括内存地址的取得,是面向对象版本的指针。
迭代子与指针有许多相同的地方,但迭代子保留所操作的特定容器需要的状态信息,从而实现与每种容器类型相适应的迭代子。
而且有些迭代子操作在所有容器中是一致的,这带来了专门大的方便。
如++运算符老是返回容器下一个元素的迭代子,就像数组指针++后指向下一个元素;间接引用符“*”,老是表示迭代子指向的容器元素,就像数组指针加*号后代表指针所指的元素。
迭代子在STL中起粘结剂的作用,用来将STL的各部份结合在一路。
从本质上说,STL提供的所有算法都是模板,咱们能够通过利用自己指定的迭代子来对这些模板实例化。
迭代子能够包括指针,但迭代子又不仅是一个指针。
11.2.2顺序容器包括哪三种?
它们各以什么数据结构为基础?
各有哪些特点?
答:
C++标准模板库提供三种顺序容器:
vector,list和deque。
vector类和deque类是以数组为基础的,list类是以双向链表为基础的。
矢量(vector)类提供了具有持续内存地址的数据结构。
它和C/C++的数组一样通过下标运算符[]直接有效地访问矢量的任何元素。
与数组不同,vector的内存用尽时,vector自动分派更大的持续内存区,将原先的元素复制到新的内存区,并释放旧的内存区。
内存分派由分派子(allocator)完成。
矢量能够用来实现队列、堆栈、列表和其他更复杂的结构。
vector支持随机访问迭代子,具有最强的功能。
vector的迭代子通常实现为vector元素的指针。
列表(list)是由双向链表(doublylinkedlist)组成的。
支持的迭代子类型为双向迭代子。
双端队列(deque)(double-endedqueue)类。
双端队列许诺在队列的两头进行操作。
它是以顺序表为基础的,因此它能利用下标提供有效的索引访问,它支持随机访问迭代子。
它放松了访问的限制,对象既可从队首进队,也能够从队尾进队,一样也可从任一端出队。
而且除可从队首和队尾移走对象外,也支持通过利用下标操作符“[]”进行访问。
当要增加双端队列的存储空间时,能够在内存块中对deque两头别离进行分派。
而且新分派的存储空间保留为指向这些块的指针数组,如此双端队列能够利用不持续内存空间。
因此它的迭代子比vector的迭代子加倍智能化。
为双端队列分派的存储块,往往要等删除双端队列时才释放,它比重复分派(再分派和释放)更有效,但也更浪费内存。
利用双端队列容器类来实现矢量容器类所能实现的各类数据结构要更灵活,方便。
11.2.3关联容器有哪四种?
简单介绍它们是如何组成的?
各有什么特点?
答:
四个关联容器为:
集合(set),多重集合(multiset),映射(map)和多重映射(multimap)。
集合和多重集合类提供了操纵数值集合的操作,其中数值是关键字,即没必要还有一组值与每一个关键字相关联。
集合与多重集合类的要紧不同在于多重集合许诺重复的关键字(key),而集合不许诺重复的关键字。
集合和多重集合通常实现为红黑二叉排序树。
元素的顺序由比较器函数对象(comparatorfunctionobject)确信。
如对整型multiset,只要用比较器函数对象less排序关键字,元素即可按升序排列。
映射和多重映射类提供了操作与关键字相关联的映射值(mappedvalue)的方式。
映射和多重映射的要紧不同在于多重映射许诺寄存与映射值相关联的重复关键字,而映射只许诺寄存与映射值一一对应的单一关键字。
多重集合关联容器用于快速存储和读取关键字。
多重映射和映射关联容器类用于快速存储和读取关键字与相关值(关键字/数值对,key/valuepair)。
11.2.4什么是函数对象?
它通经常使用在什么地址?
答:
函数对象是一个类,它重载了函数挪用操作符(operator())。
该操作符封装了应该被实现为一个函数的操作。
典型情形下,函数对象被作为实参传递给泛型算法,以完全解决类型依托性的问题。
和“引用”一样,“函数对象”很少独立利用。
函数对象与函数指针相较较有三个优势:
第一,函数指针是间接引用,不能作为内联函数,而函数对象能够,如此速度更快;第二,类有数据域,函数对象能够拥有任意数量的额外数据,用这些数据能够用来缓冲当前数据和结果,提高运行质量;第三,编译时对函数对象作类型检查。
11.2.5泛型算法函数名加有后缀_if是什么意思?
而加有后缀_copy又代表什么意思?
答:
_if表示函数采纳的操作是在元素上(知足给定谓词),而不是对元素的值本身进行操作。
如find_if算法表示:
在容器指定范围中查找一些特点知足函数指定条件的(知足给定谓词)元素,也确实是使某一函数对象返回值第一次为真的元素。
例如;小于特定值的第一个元素。
而find查找含特定值的第一个元素。
_copy表示算法不仅操作元素的值,而且还把修改的值复制到一个目标范围中。
如reverser算法倒置范围中元素的排列顺序,而reverse_copy算法同时把结果复制到目标范围中。
二.编程题与综合练习题
11.3编程测试顺序容器矢量(vector)的要紧功能和利用方式。
(参考附录C,下同)
解:
#include
#include
#include
#include
usingnamespacestd;
intmain(){
ostream_iteratoroutput(cout,"");
//用输出迭代子output来输出,其中第二参数""表示用空格分隔各个整数。
intia[18]={47,29,5,37,13,23,11,61,7,31,41,2,59,19,17,53,43,3};
vectorvec(ia,ia+9);//数据填入vector;vector共有7个构造函数,经常使用3个
//vector(),用以声明空的vector;vector(n),用以声明有n个元素的vector;
//vector(first,last),用以声明一个vector,
//其元素的初值是从区间[first,last)所指定的序列中的元素复制而来的;
vectorvec2(18);
if(())cout<<"vector空"<else{
cout<<"vector不空,"<<"vector中的元素:
"<unique_copy((),(),output);
cout<}
cout<<"当前分派元素空间数量:
"<<()<(12);
cout<<"当前为vector保留的最小分派元素空间数量:
"<<()<((),());
cout<<"当前分派元素空间数量:
"<<()<(10);
cout<<"当前从头分派元素空间数量为10,实际分派元素空间数量:
"
<<()<(ia+10,ia+16);
cout<<"vector寄存序列允许最大长度:
"<cout<<"vector中的元素:
"<unique_copy((),(),output);
cout<(ia,ia+18);
cout<<"vector中的元素:
"<unique_copy((),(),output);
cout<sort((),(),greater());//降序排列
cout<<"vector中的元素:
"<unique_copy((),(),output);
cout<cout<<"用反转迭代子输出vector中的元素:
"<unique_copy((),(),output);
cout<"<<()<cout<<"最后1个元素:
"<<()<cout<<"第8个元素:
"<cout<<"原vector2中的元素:
"<unique_copy(vec2.begin(),vec2.end(),output);
cout<vec2.swap(vec);
cout<<"互换后vector2中的元素:
"<unique_copy(vec2.begin(),vec2.end(),output);
cout<return0;
}
11.4编程测试顺序容器列表(list)的要紧功能和利用方式。
解:
#include
#include
#include
#include
usingnamespacestd;
intmain(){
ostream_iteratoroutput(cout,"");
//用输出迭代子output来输出,其中第二参数""表示用空格分隔各个整数。
intia[18]={47,29,5,37,13,23,11,61,7,31,41,2,59,19,17,53,43,3};
listlist1(ia,ia+18);//数据填入list1;list共有7个构造函数,经常使用3个
//list(),用以声明空的list;list(n),用以声明有n个元素的list;
//list(first,last),用以声明一个list,
//其元素的初值是从区间[first,last)所指定的序列中的元素复制而来的;
listlist2(18);
if(list1.empty())cout<<"list1空"<else{
cout<<"list1不空,"<<"list1中的元素:
"<unique_copy(list1.begin(),list1.end(),output);
cout<}
list1.sort(greater());//降序排列
cout<<"list1中的元素降序排列:
"<unique_copy(list1.begin(),list1.end(),output);
cout<cout<<"用反转迭代子输出list1中的元素:
"<unique_copy(list1.rbegin(),list1.rend(),output);
cout<"<cout<<"最后1个元素:
"<cout<<"原list2中的元素:
"<unique_copy(list2.begin(),list2.end(),output);
cout<list2.swap(list1);
cout<<"互换后list2中的元素:
"<unique_copy(list2.begin(),list2.end(),output);
cout<cout<<"现list1中的元素空了:
"<unique_copy(list1.begin(),list1.end(),output);
cout<list1.assign(list2.begin(),list2.end());
cout<<"将list2的元素赋到list1中:
"<unique_copy(list1.begin(),list1.end(),output);
cout<list2.resize(10);
cout<<"list2中的元素应剩10个:
"<unique_copy(list2.begin(),list2.end(),output);
cout<back();
cout<<"现list1中的元素:
"<unique_copy(list1.begin(),list1.end(),output);
cout<front();
cout<<"现list1中的元素:
"<unique_copy(list1.begin(),list1.end(),output);
cout<back(ia[17]);
cout<<"因原list1中最后的元素与新插入元素相同,未能真正插入:
"<unique_copy(list1.begin(),list1.end(),output);
cout<front(ia[0]);
cout<<"现list1中的元素:
"<unique_copy(list1.begin(),list1.end(),output);
cout<return0;
}
11.5编程测试以双向队列(deque)为基础的容器适配器队列(queue)的要紧功能和利用方式。
解:
#include
#include
#include
usingnamespacestd;
intmain(){
inti,j;
doubleda[10]={3.1,4.2,84.5,18.3,6.8,5.9,8.3,22.8,1.23,4.7};
queueque1;
for(i=0;i<10;i++)que1.push(da[i]);
for(i=0;i<10;i++){
cout<que1.pop();
}
cout<return0;
}
11.6利用映射(map),成立阿拉伯的数字0~9和英文单词Zero到Nine的映射关系,并输入阿拉伯数字(如:
1),输出英文数字(如:
One)。
解:
#include<>
#include
usingnamespacestd;
typedefmapismap;
intmain(){
inti=1,j;
char*str[10]={"one","two","three","fore","five","six","sever","eight","nine","ten"};
ismaptrans_map1;
ismap:
:
iteratorit;
for(i=1;i<=10;i++)trans_map1.insert(ismap:
:
value_type(i,str[i-1]));
for(it=trans_map1.begin();it!
=trans_map1.end();it++)
cout<<(*it).first<<'\t'<<(*it).second<cout<cout<<"请输入1~10的数字:
"<cin>>j;
it=trans_map1.find(j);
cout<<(*it).first<<'\t'<<(*it).second<return0;
}