C++Prime 第九章前30题

C++Prime  第九章前30题

练习9.1

(a)选择list,因为可能在容器中间插入元素.也可以选择vector,全部读取完毕后,直接sort.

(b)选择deque,因为插入删除操作只在头部进行.

(c)选择vector.

练习9.2

	list<deque<int> > data;

练习9.3

迭代器范围:两个迭代器指向同一容器,或者是容器最后一个元素之后的位置,begin递增若干次后等于end.

练习9.4

#include <iostream>
#include <list>
#include <string>
#include <vector>
#include <forward_list>
#include <deque>
using namespace std;

typedef vector<int>::iterator Iter;
bool find_value(Iter beg, Iter end, int n)
{
	auto p = beg;
	while (p != end)
		if (*p++ == n)
			return true;
	return false;
}
int main()
{
	vector<int> data{ 1,2,3,4,5,6,7 };
	if (find_value(data.begin(), data.end(), 3))
		cout << "find it\n";
	else
		cout << "Don't find!\n";

	return 0;
}

练习9.5

#include <iostream>
#include <list>
#include <string>
#include <vector>
#include <forward_list>
#include <deque>
using namespace std;

typedef vector<int>::iterator Iter;
Iter find_value(Iter beg, Iter end, int n)
{
	auto p = beg;
	while (p != end)
	{
		if (*p == n )
			return p;
		p++;
	}
	return p;
}
int main()
{
	vector<int> data{ 1,2,3,4,5,6,7 };
	if (data.end() != find_value(data.begin(), data.end(), 3))
		cout << "find it\n";
	else
		cout << "Don't find!\n";

	return 0;
}

练习9.6

只有vector string array deque的迭代器可以执行关系运算.改正: while(iter1 != iter2)

练习9.7

		vector<int>::size_type;
	//or
	vector<int>::iterator;//const_iterator

练习9.8

	string::const_iterator;
	list<string>::iterator;

练习9.9

begin()的返回值取决于容器的类型.容器是const 的,则begin()返回的是const_iterator,否则返回iterator

cbegin()一定返回常量迭代器const_iterator

练习9.10

it1是vector<int>::iterator

it2,it3,it3是vector<int>::const_iterator

练习9.11

	vector<int> a1;//默认初始化,空对象
	
	vector<int> a2(a1);//a2 == a1
	vector<int> a22 = a1; //a22 == a1

	vector<int> a3{ 1,2,3 }; //a2 == {1,2,3}
	vector<int> a32 = { 1,2,3 };

	vector<int> a4(a3.begin(), a3.end()); //a4 == a3
	vector<int> a42(a3.begin(), a3.begin() + 2);

	vector<int> a5(10);//10个0
	vector<int> a6(10, 2);//10个2

练习9.12

接受一个容器创建其copy要求 :两个容器类型必须相同,元素类型必须相同.

接受两个迭代器创建copy的构造函数:两个容器类型可以不同,元素类型也可以不同(要能转换成接受容器的元素类型)

练习9.13

	list<int> a{1,2,3,4};
	vector<double> b(a.begin(),a.end());
	for (const auto& x : b)
		cout << x << " ";
	cout << endl;

练习9.14

	list<char*> lc;
	vector<string> data;
	data.assign(lc.begin(), lc.end());

练习9.15

#include <iostream>
#include <list>
#include <string>
#include <vector>
#include <forward_list>
#include <deque>
using namespace std;

int main()
{
	list<int> k1{ 1,2,3,4 };
	list<int>k2{ 1,3 };
	if (k1 == k2)
		cout << "相等" << endl;
	else
		cout << "不等" << endl;
	return 0;
}

练习9.16

方法一:逐个元素比较,还要考虑两个容器长度不等的情况.

方法二:先用list初始化一个vector<int>,然后比较两个vector<int>即可,代码简洁,效率不如方法一.

练习9.17

三点限制.

其一:c1和c2必须是相同类型的容器.

其二:c1和c2的元素类型必须相同.

其三:c1和c2的元素必须支持"="和"<"运算符.比如没有重载"="或"<"的自定义类,不能按照题目判断.

练习9.18

#include <iostream>
#include <list>
#include <string>
#include <vector>
#include <forward_list>
#include <deque>
#include <algorithm>
using namespace std;

template<class T>
void print(const T& t)
{
	for (const auto x : t)
		cout << x << " ";
	cout << endl<<endl;
}

int main()
{
	deque<string> data;
	string tmp;
	while (cin >> tmp ) //从头插入
		data.push_front(tmp);
	print(data);
	cin.clear();

	deque<string> data2;
	while (cin >> tmp)//从尾部插入
		data2.push_back(tmp);
	print(data2);
	cin.clear();

	deque<string> data3;
	auto ptr = data3.begin();
	while (cin >> tmp)//从头插入,使用insert,并且使用insert的返回值
		ptr = data3.insert(ptr, tmp);
	print(data3);
	cin.clear();

	deque<string> data4;
	auto ptr2 = data4.end();
	while (cin >> tmp )//从尾部倒着往前插入
		ptr2 = data4.insert(ptr2, tmp);
	print(data4);
	cin.clear();

	deque<string> data5;
	while (cin >> tmp )
		data5.emplace_back(tmp);//使用C++11新标准的emplace,注意emplace的参数要符合某个构造函数
	print(data5);
	cin.clear();

	deque<string> data6;
	auto ptr3 = data6.begin();
	while (cin >> tmp )//可以看出emplace和insert返回值的规则应该是相同的,书中没有提及.
		ptr3 = data6.emplace(ptr3, tmp);

	return 0;
}

练习9.19

list和deque可以使用inset,push_back,push_front,emplce所有函数,本体直接把deque换成list无问题.

vector和string,不能使用头插类的两个push_front和emplace_front,insert没问题,用insert来实现头部插入

forward_list不支持尾插的两个,同时insert和emplace也是自己的专有版本.

array不支持上述所有.

虽然支持,却不一定最优,合理选择容器和方法.

练习9.20

#include <iostream>
#include <deque>
#include <string>
#include <vector>
#include <forward_list>
#include <list>
#include <algorithm>
using namespace std;

template<class T>
void print(const T& t)
{
	for (const auto x : t)
		cout << x << " ";
	cout << endl<<endl;
}

int main()
{
	list<int> data{1,2,3,4,5,6};
	deque<int> d1, d2;
	for (auto p = data.begin(); p != data.end(); ++p)
	{
		int num = *p % 2;
		if (num)
			d1.push_back(*p);
		else 
			d2.push_back(*p);
	}
	print(d1);
	print(d2);
	return 0;
}

练习9.21

每一次插入都要移动当前所有元素,极其无效率.

练习9.22

对vector,string,deque(就是除了链表的那些) 一旦插入数据,迭代器,指针,引用全部失效.

修改:

不会!

练习9.23

全为首元素的值,

练习9.24

int main()
{
	vector<int> data;
	try
	{
		cout << data.at(0) << endl;
	}
	catch (out_of_range) {
		cout << "下标范围不对" << endl;
	}
	data.push_back(123);
	if (!data.empty())
	{
		cout << data[0] << endl;
		cout << data.front() << endl;
		cout << *data.begin() << endl;
	}
	return 0;
}

练习9.25

范围的两个迭代器相等,不删.

第二个迭代器时尾后,第一个不是尾后,则删除第一个迭代器所指及其后的所有元素

都是超尾迭代器.不删,

练习9.26

#include <iostream>
#include <deque>
#include <string>
#include <vector>
#include <forward_list>
#include <list>
#include <algorithm>
#include <exception>
using namespace std;

template<class T>
void print(const T& t)
{
	for (const auto x : t)
		cout << x << " ";
	cout << endl<<endl;
}

int main()
{
	int ia[] = { 0,1,2,3,5,8,13,21,55,89 };
	vector<int> vi(begin(ia),end(ia));
	list<int> li(vi.begin(),vi.end());
	print(vi);
	print(li);
	cout << "删除后:\n";
	auto p = vi.begin();
	while(p != vi.end())
	{
		if (!(*p % 2))
			p = vi.erase(p);
		else
			++p;
	}

	auto q = li.begin();
	while (q != li.end())
	{
		if (*q % 2)
			q = li.erase(q);
		else
			++q;
	}
	print(vi);
	print(li);


	return 0;
}

练习9.27

	forward_list<int> a{1,2,3,4,5,6,7,8};
	auto pre = a.before_begin();
	auto p = a.begin();
	while (p != a.end())
	{
		if (*p % 2)
			p = a.erase_after(pre);
		else
		{
			pre = p;
			++p;
		}
	}

练习9.28

#include <iostream>
#include <deque>
#include <string>
#include <vector>
#include <forward_list>
#include <list>
#include <algorithm>
#include <exception>
using namespace std;

template<class T>
void print(const T& t)
{
	for (const auto x : t)
		cout << x << " ";
	cout << endl<<endl;
}

void insertToList(forward_list<string> &word,const  string& s1, const string& s2)
{
	auto pre = word.before_begin(), p = word.begin();
	bool find_s1 = false;
	while (p != word.end())
	{
		if (*p == s1)
		{
			find_s1 = true;
			p = word.insert_after(p, s2);
			break;
		}
		else
		{
			pre = p;
			++p;
		}
	}
	if (!find_s1)
		p = word.insert_after(pre, s2);
}

int main()
{
	forward_list<string> word;
	auto p = word.before_begin();
	string wd;
	while (cin >> wd)
		p = word.insert_after(p,wd);
	cout << "插入前:" << endl;
	print(word);
	cout << "输入两个字符:第一个查找,第二个插入." << endl;
	string s1, s2;
	cin.clear();
	cin >> s1 >> s2;
	insertToList(word, s1, s2);
	cout << "插入后:" << endl;
	print(word);
	return 0;
}

练习9.29

扩充75的容量,新元素执行值初始化.

删除后部90个元素.

练习9.30

resize的要求如果是类类型,要么该类具有默认构造函数,要么显示初始化

既然是单参数版本的resize,这个唯一的参数用来指明容量的大小,则无法进行显示初始化,故类必须包含默认构造方法

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值