C++ Primer 第九章 顺序容器 1

mac2026-05-21  6

9.9 begin 和 cbegin 两个函数有什么不同?

答:(1) cbegin() 是C++新标准引入的,用以支持auto与begin()和end()函数使用的。它返回的是容器第一个元素的const迭代器,只能够以只读形式访问容器元素,不能够通过它修改元素内容。当不需要写访问时,应该使用cbegin(). (2)begin()是被重载过的,也就是说实际上是有两个begin成员,一个是const类型的成员,返回的是是const_iterator类型;另一个是非常量类型,返回的实际 iterator, 可以对容器类型进行修改。


9.10 下面四个对象分别是什么类型?

vector<int> v1; const vecto<int> v2; auto it1 = v1.begin(); auto it2 = v2.begin(); auto it3 = v1.cbegin(); auto it4 = v2.cbegin(); 答: v1 是 int的vector类型,可以修改v1的内容, v2 是 int的常量vector类型,不可以修改v2的内容。it1是普通非常量迭代器,it2 是常量迭代器。it3和it4都是常量迭代器。

9.11 对6种创建和初始化vector对象的方法,每一种都给出一个实例,解释每个vector包含什么值?

答: vector<int> i = {0, 1, 2}; // 列表初始化 vector<int> ivec{0, 1, 2}; // 列表初始化 vector<int> ivec; // ivec 为空 vector<int> ivec(i); // ivec初始化拷贝 i,其中元素与i 相等 vector<int> ivec = i; // 与上一句相同 vector<int> ivec(i.begin(), i.end()); // ivec包含i的首元素与尾元素之间的元素 vector<int> ivec(10); // ivec包含10个元素,每个元素都初始化为0 vector<int> ivec(10, 2); // ivec包含10个元素,每个元素都初始化为2 >

9.12 对于接受一个容器创建其拷贝的构造函数,和接受两个迭代器创建拷贝的构造函数,解释他们的不同?

答:接受一个已有容器的构造函数会拷贝该容器的所有元素,即是该容器的完整拷贝。当我们需要对一个容器进行完整的拷贝时,这种初始化是非常方便的。创建容器的拷贝时,两个容器的类型必须相同,且其所存储元素的类型也必须相同。当不需要已有容器的全部元素时,可以使用接受两个迭代器创建拷贝的构造函数,选择自己需要元素子集。因为该方法是从迭代器中读取相应的元素,所以两个容器的类型不需要相同,只需保证容器中的元素类型相同,或者可以转化为初始化容器中的元素类型即可。

9.13 如何从一个list初始化一个vector?从vector又该如何创建?编写代码验证你的答案

答:从其他类型容器初始化另一个类型的容器,只有使用迭代器范围初始化这一方式。虽然vector与vector的容器类型相同,但是其元素类型不同,所以不能够使用容器直接初始化。 #include <iostream> #include <list> #include <vector> using namespace std; int main(int argc, char* argv[]) { { list<int> ilist = { 0, 1, 2 }; // 初始化 ilist auto begin = ilist.cbegin(); // 首元素迭代器 auto end = ilist.cend(); // 尾元素之后的迭代器 vector<double> dvec(begin, end); // 使用迭代器初始化 dvec for (auto i : dvec) { cout << i << endl; } } { vector<int> ivec = { 0, 1, 2 }; auto begin = ivec.cbegin(); auto end = ivec.cend(); //vector<double> dvec(ivec); // 此处会报错提示,元素类型不同 vector<double> dvec(begin, end); for (auto i : dvec) { cout << i << endl; } } return 0; }

** 9.14 编写程序,将一个list中的 char* 指针(指向c风格字符串)元素赋值给一个vector中的string**

答:因为涉及到不同容器之间的赋值,所以需要使用迭代其,即使用assign(b, e)进行赋值操作。 #include <iostream> #include <list> #include <vector> using namespace std; int main(int argc, char* argv[]) { list<const char*> clist = { "A", "B", "C" }; vector<string> svec; auto begin = clist.cbegin(); auto end = clist.cend(); svec.assign(begin, end); for (auto i : svec) { cout << i << endl; } return 0; }

** 9.15 编写程序,判断两个 vector< int > 是否相等**

答: #include <iostream> #include <list> #include <vector> #include <string> using namespace std; int main(int argc, char* argv[]) { vector<int> ivec1{ 1, 2, 3 }; vector<int> ivec2{ 1, 2, 3, 4 }; bool flag = (ivec1 == ivec2); cout << boolalpha; cout << flag << endl; return 0; }

** 9.16 重写上一题程序,比较一个 list< int>中的元素和一个 vector< int> 中的元素。**

答:该题有两种思路。第一种是对读取容器中的元素进行比较,因为容器类型不同,所以无法直接应用关系运算符。第二种思路是将list中的元素内容直接拷贝到新建的vector中,然后直接使用关系运算符进行比较,比较方便,但是创建新的容器会额外占用内存,并且拷贝数据需要额外时间。(但是实际测出来的效果,第二种时间比较少,大家可以试一试) #include <iostream> #include <list> #include <vector> #include <string> #include<Windows.h> using namespace std; bool list_vec_equal(list<int>, vector<int>); int main(int argc, char* argv[]) { list<int> ilist{ 1, 2, 3, 4, 5, 6, 7 ,8 ,9 ,10 }; vector<int> ivec{ 1, 2, 3, 4, 5, 6, 7 ,8 ,9 ,10, 11 }; double sum1 = 0, sum2 = 0; { for (int i = 0; i < 10000; i++) { DWORD64 start, finish; double time; start = GetTickCount64(); bool flag = list_vec_equal(ilist, ivec); finish = GetTickCount64(); time = finish - start; sum1 = sum1 + time; cout << boolalpha; cout << flag << "运行时间 " << time << " ms" << endl; } } { for (int j = 0; j < 10000; j++) { DWORD64 start, finish; double time; start = GetTickCount64(); vector<int> ivec2(ilist.cbegin(), ilist.cend()); bool flag = (ivec == ivec2); finish = GetTickCount64(); time = finish - start; sum2 = sum2 + time; cout << boolalpha; cout << flag << "运行时间 " << time << " ms" << endl; } } cout << sum1 << " " << sum2 << " ms" << endl; return 0; } bool list_vec_equal(list<int> ilist, vector<int> ivec) { auto begin1 = ilist.cbegin(); auto end1 = ilist.cend(); auto begin2 = ivec.cbegin(); if (ilist.size() != ivec.size()) { cout << false << endl; return false; } for (; begin1 != end1; begin1++, begin2++) { if (*begin1 != *begin2) return false; } return true; }

** 9.17 假定 c1 和 c2 是两个容器,下面的比较操作有和限制,如果有的话?**

if (c1 < c2) 答:首先,c1与c2必须是相同类型的容器,且元素类型相同。其次,元素类型需支持 “<” 关系运算符。
最新回复(0)