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

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必须是相同类型的容器,且元素类型相同。其次,元素类型需支持 “<” 关系运算符。
发布了38 篇原创文章 · 获赞 29 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/ruotianxia/article/details/102870506