c++primer第五版第九章练习

9.1

a vector或duque

b duque

c vector


9.2

list> ldint;


9.3

需指向同一个容器 不能在begin之前


9.4

bool findint(vector::iterator b,vector::iterator e,int n)
{
	auto iter=b;
	while(iter!=e)
	{
		if(*iter==n)
			return true;
        ++iter;
	}
	return false;
}

9.5

vector::iterator findint(vector::iterator b,vector::iterator e,int n)
{
	auto iter=b;
	while(iter!=e)
	{
		if(*iter==n)
			return iter;
++iter;
	}
	return NULL;
}


9.6

操作符 < 不能用于list的迭代器

while(iter1!=iter2) /* ... */

9.7

vector::size_type


9.8

题目是"读取" list::iterator 或者是 list::const_iterator 都行,看程序是否需要修改

写入 list::iterator


9.9

begin返回的是iterator迭代器,可用解引用运算符进行修改值,而cbegin返回的是const_iterator,无法通过解引用修改


9.10

it1 iterator it2、it3、it4const_iterator


9.11

1 vector vint;//空

2 vector vint(10);//10个值为零的元素

3 vector vint(10,1);//10个值为1的元素

4 vector vint{1,2,3};//3个值,分别为1 2 3

5 vector vint(beg,end);//内容为迭代器beg到end前的元素

6 vector vint(vint2);//内容为容器vint2的元素


9.12

接受一个容器必须是同类型的,而且是全部复制,接受迭代器的只需要对象的基本类型相同或可以转换即可而且还可以指定范围


9.13

#include 
#include 
#include 

int main()
{
	using namespace std;
	list lint = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	vector vint = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	vector vd1(lint.begin(),lint.end());
	vector vd2(vint.begin(), vint.end());
	for (auto x : vd1)
		cout << x;
	for (auto x : vd2)
		cout << x;
	system("pause");
	return 0;
}

9.14

#include 
#include 
#include 
#include 

int main()
{
	using namespace std;
	list lcp = { "123", "abc", "[];" };
	vector vstr;
	vstr.assign(lcp.begin(), lcp.end());
	for (auto &x : vstr)
		cout << x << endl;

	system("pause");
	return 0;
}

9.15

#include 
#include 

int main()
{
	using namespace std;
	vector vint1 = { 1, 2, 3, 4, 5 };
	vector vint2 = { 1, 2, 3, 4, 5 };
	vector vint3 = { 1, 2, 3, 4 };
	cout << "vint1==vnt2 :" << (vint1 == vint2 ? "yes" : "no") << endl;
	cout << "vint1==vnt3 :" << (vint1 == vint3 ? "yes" : "no") << endl;
	system("pause");
	return 0;
}

9.16

#include 
#include 
#include 
int main()
{
	using namespace std;
	list lint = { 1, 2, 3, 4, 5 };
	vector vint1 = { 1, 2, 3, 4, 5 };
	vector vint2 = { 2, 3, 4, 5 };
	cout << (vector(lint.begin(), lint.end()) == vint1 ? "yes" : "no") << endl;
	cout << (vector(lint.begin(), lint.end()) == vint2 ? "yes" : "no") << endl;
	system("pause");
	return 0;
}

9.17

c1和c2必须是同类型的容器,而且基本类型必须相同

基本类型必须支持"<"运算符


9.18

#include 
#include 
#include 

int main()
{
	using namespace std;
	deque ds;
	string temp;
	while (cin >> temp)
	{
		ds.push_back(temp);
	}
	auto iter = ds.cbegin();
	while (iter != ds.cend())
	{
		cout << *iter++ << "\t";
	}
	system("pause");
	return 0;
}

9.19

#include 
#include 
#include 

int main()
{
	using namespace std;
	list ds;
	string temp;
	while (cin >> temp)
	{
		ds.push_back(temp);
	}
	auto iter = ds.cbegin();
	while (iter != ds.cend())
	{
		cout << *iter++ << "\t";
	}
	system("pause");
	return 0;
}

9.20

#include 
#include 
#include 
int main()
{
	using namespace std;
	list li;
	int temp;
	while (cin >> temp)
		li.push_back(temp);
	deque di1, di2;
	auto iterb = li.cbegin(), itere = li.cend();
	while (iterb != itere)
	{
		if (*iterb % 2 == 0)
			di1.push_back(*iterb);
		else
			di2.push_back(*iterb);
		++iterb;
	}
	for (auto x : di1)
		cout << x << "\t";
	cout << endl;
	for (auto x : di2)
		cout << x << "\t";
	system("pause");
	return 0;
}

9.21

相同,因为list的insert和vector的insert都是把值插入都迭代器之前和返回插入元素的迭代器。


9.22

死循环,iter的值没有改变

因为进行了insert操作,所以iter和mid迭代器失效(因为insert操作会把元素插入到iter之前,所以iter也失效)

while (iter != mid)
{
	if (*mid == some_val)
		mid = iv.insert(mid, 2 * some_val);
	else
		--mid
}

9.23

所有值都指向第一个元素


9.24

#include 
#include 
int main()
{
	using namespace std;
	vector vint;
	cout << vint.at(0);
	cout << vint[0];
	cout << vint.front();
	cout << *vint.begin();
	system("pause");
	return 0;
}

9.25

elem1==elem2 erase将删除elem1到elem2之前的元素[elem1,elem2) 也就是说什么也没发生

如果elem2是尾后迭代器,将删除elem1到结尾的所有元素

如果elem1和elem2都是尾迭代器然而还是什么都没发生


9.26

#include 
#include 
#include 

int main()
{
	using namespace std;
	int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
	list lint(ia, end(ia));
	vector vint(ia, end(ia));
	auto iter = lint.begin();
	while (iter != lint.end())
	{
		if (*iter % 2)
			iter = lint.erase(iter);
		else
			++iter;
	}
	auto iter1 = vint.begin();
	while (iter1 != vint.end())
	{
		if (!(*iter1 % 2))
			iter1 = vint.erase(iter1);
		else
			++iter1;
	}
	for (auto x : lint)
		cout << x << "\t";
	for (auto x : vint)
		cout << x << "\t";
	system("pause");
	return 0;
}

9.27

#include 
#include 
int main()
{
	using namespace std;
	forward_list fli;
	int temp;
	while (cin >> temp)
	{
		fli.push_front(temp);
	}
	auto iter = fli.before_begin(),beg=fli.begin();
	while (beg != fli.cend())
	{
		if (*beg % 2)
			beg = fli.erase_after(iter);				//删除iter地址的下一个元素,即iter位置的元素 该方法返回被删元素的下一个地址
		else
			iter = beg++;						//把iter设为beg之前
	}
	for (auto x : fli)
		cout << x << "\t";
	system("pause");
	return 0;
}

9.28

#include 
#include 
#include 
void flsf(std::forward_list &t, const std::string &s, const std::string &e);	
//接受一个string的forward list对象和两个string,在s出现的位置后插入e,没有找到s就在末尾插入e
int main()
{
	using namespace std;
	forward_list fls;
	string temp;
	auto iter = fls.before_begin();
	while (cin >> temp)
	{
		iter=fls.insert_after(iter,temp);
	}
	flsf(fls, string("nonororo"), string("ikaro"));
	for (auto &x : fls)
		cout << x << " ";
	system("pause");
	return 0;
}
void flsf(std::forward_list &t, const std::string &s, const std::string &e)
{
	auto iter = t.begin();
	std::cout << "fun" << std::endl;
	auto tend = iter;
	while (iter != t.end())
	{
		if (*iter == s)
		{
			t.insert_after(iter, e);
			return;
		}
		tend = iter++;
	}
	t.insert_after(tend, e);
}

9.29

在vec后面添加75个元素,值为默认构造

只保留前10个的值,其他的删除


9.30

基础类型必须有默认构造函数


9.31

list和forward_list没有定于"+=2"的操作,forward_list只有insert_after和erase_after

list:

#include 
#include 

int main()
{
	using namespace std;
	list li = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto iter = li.begin();
	while (iter != li.end())
	{
		if (*iter % 2)
		{
			iter = li.insert(iter, *iter);
			++iter; ++iter;
		}
		else
			iter = li.erase(iter);
	}
	for (auto x : li)
		cout << x << "\t";
	system("pause");
	return 0;
}
forward_list:

#include 
#include 
int main()
{
	using namespace std;
	forward_list fli = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto iter = fli.begin(), siter = fli.before_begin();
	while (iter != fli.end())
	{
		if (*iter % 2)
		{
			iter = fli.insert_after(siter, *iter);
			++iter;					//跳过最后插入的元素与原有元素
			siter=iter++;				//把siter设为iter的前一个
		}
		else
		{
			iter = fli.erase_after(siter);		//删除迭代器的下一个元素,并把删除后元素的下一个地址返回
		}
	}
	for (auto x : fli)
		cout << x << "\t";
	system("pause");
	return 0;
}

9.32

不合法,不同编译器不同结果

因为调用insert时iter的值可能如期望的iter也可能是iter+1,这个视编译器而异


9.33

在使用insert插入新元素后原有迭代器失效

#include 
#include 
using std::vector; using std::cout; using std::endl;
int main()
{
	vector v{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto begin = v.begin();
	while (begin != v.end()) {
		++begin;
		v.insert(begin, 42);
		++begin;
	}
	for (auto i : v)
		cout << i << " ";
	system("pause");
	return 0;
}


9.34

复制奇数并插入到原奇数之前,但是本题的while喜欢只是对if有效,++iter无效,可能是书本错误

并且根据书上的iter会一直指向第一个奇数,是死循环

改变后:

#include 
#include 
int main()
{
	using namespace std;
	vector vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto iter = vi.begin();
	while (iter != vi.end())
	{
		if (*iter % 2)
		{
			iter = vi.insert(iter, *iter);
			iter += 2;
		}
		else
		{
			++iter;
		}
	}
	for (auto x : vi)
		cout << x << "\t";
	system("pause");
	return 0;
}

9.35

capacity是容器当前已分配的内存,表示当前最大容量

size是当前容器已有的元素的数量


9.36

不可能,最多是与size相等,当size大于capacity时会自动分配内存


9.37

list是链表,空间不是连续的

array的空间是定义时就固定的,无法改变


9.38

视编译器而异,本机是capacity在小于size自动增长为size的150%左右

#include 
#include 

int main()
{
	using namespace std;
	vector vi;
	cout << vi.size() << "\t" << vi.capacity() << endl;
	for (int i = 0; i<100; ++i)
		vi.push_back(i);
	cout << vi.size() << "\t" << vi.capacity() << endl;
	vi.shrink_to_fit();
	cout << vi.size() << "\t" << vi.capacity() << endl;
	vi.push_back(0);
	cout << vi.size() << "\t" << vi.capacity() << endl;
	system("pause");
	return 0;
}

9.39

一直从cin读取字符串到word并压入svec中,虽然svec设置了reserve(100),但这只是说明reserve在不进行新的空间分配的情况下最大我100个,但是当读取到101个时还是会自动增加空间(本机是150%左右地增加,即变成150),直到cin遇到结束字符或vector到达max_size。

然后调用resize重设大小为当前元素个数的150%,多出的50%的值为基本类型的默认构造函数


9.40

256 384     573
512 768     1149

....

#include 
#include 
int main()
{
	using namespace std;
	vector vi;
	for (int i = 0; i < 255; ++i)
		vi.push_back(i);
	vi.shrink_to_fit();
	vi.push_back(1);
	cout << vi.size() << "\t" << vi.capacity() << endl;
	vi.resize(vi.size() + vi.size() / 2);
	cout << vi.size() << "\t" << vi.capacity() << endl;
	system("pause");
	return 0;
}

9.41

#include 
#include 
#include 
int main()
{
	using namespace std;
	vector vc = { 'i', 'k', 'a', 'r', 'o' };
	string str(vc.begin(), vc.end());		//通过迭代器范围初始化
	cout << str << endl;
	system("pause");
	return 0;
}

9.42

使用reserve来分配更大的预存空间,避免重新分配内存的消耗


9.43

#include 
#include 
void freplace(std::string &s, const std::string &o, const std::string &n);//从s里面查找o的内容并全部替换为n
int main()
{
	using namespace std;
	string str, old, news;
	getline(cin, str);
	cout << "old new:";
	cin >> old >> news;
	freplace(str, old, news);
	cout << str << endl;
	system("pause");
	return 0;
}
void freplace(std::string &s, const std::string &o, const std::string &n)
{
	if (s.size() < o.size()||s.empty()||o.empty())				//n可以为空,代表删除
		return;
	for (auto iter = s.begin(); iter <= (s.end()-o.size()+1); ++iter)	//如果iter到达s的倒数第o.size()-1个元素,小于o大小的字符串后不需要检查
	{
		if (s.substr(iter-s.begin(),o.size()) == o)			//iter迭代器的位置减去头位置,得到距离,然后复制o.size()个,意思就是返回一个和o对象大小相同的string引用方便对比
		{
			iter = s.erase(iter, iter + o.size());			//删除匹配的范围
			iter = s.insert(iter, n.cbegin(), n.cend());		//插入新的内容,相对于替换就内容为n
			iter += n.size();					//跳过插入的元素
		}
	}
}

9.44

#include 
#include 
void freplace(std::string &s, const std::string &o, const std::string &n);//从s里面查找o的内容并全部替换为n
int main()
{
	using namespace std;
	string str, old, news;
	getline(cin, str);
	cout << "old new:";
	cin >> old >> news;
	freplace(str, old, news);
	cout << str << endl;
	system("pause");
	return 0;
}
void freplace(std::string &s, const std::string &o, const std::string &n)
{
	if (s.size() < o.size() || s.empty() || o.empty())			//n可以为空,代表删除
		return;
	std::string::size_type i = 0;
	while(i <= (s.size() - o.size()))
	{
		if (s.substr(i, o.size()) == o)
		{
			s.replace(i, o.size(), n);
			i += n.size();
		}
		else
			++i;
	}
}


9.45

#include 
#include 

std::string newstr(const std::string &s, const std::string &f, const std::string &l);

int main()
{
	using namespace std;
	string name, fname, lname;
	cout << "nme fname name:";
	cin >> name >> fname >> lname;
	name = newstr(name, fname, lname);
	cout << name << endl;
	system("pause");
	return 0;
}
std::string newstr(const std::string &s, const std::string &f, const std::string &l)
{
	std::string str = s;
	str.insert(str.begin(), f.begin(), f.end());
	str.append(l);
	return str;
}

9.46

#include 
#include 
std::string newstr(const std::string &s, const std::string &f, const std::string &l);
int main()
{
	using namespace std;
	string name, fname, lname;
	cout << "nme fname name:";
	cin >> name >> fname >> lname;
	name = newstr(name, fname, lname);
	cout << name << endl;
	system("pause");
	return 0;
}
std::string newstr(const std::string &s, const std::string &f, const std::string &l)
{
	std::string str = s;
	str.insert(str.begin(), f.begin(), f.end());
	str.insert(str.end(), l.begin(), l.end());
	return str;
}


9.47

#include 
#include 
void fshowe(const std::string &s);
void fshown(const std::string &s);
int main()
{
	using namespace std;
	string str("ab2c3d7R4E6");
	fshowe(str);
	cout << endl;
	fshown(str);
	system("pause");
	return 0;
}
void fshown(const std::string &s)
{
	std::string n = {"1234567890" };
	for (std::string::size_type i = 0; i 

9.48

string:npos


9.49

#include 
#include 
#include 
int main(int argc, char **argv)
{
	using namespace std;
	ifstream ifile(argv[1]);
	string e = "acenmorsuvwxz";
	string str,maxstr;
	string::size_type msize = 0;
	while (ifile >> str)
	{
		if (str.find_first_not_of(e) == string::npos&&str.size() > msize)	//如果没有在str中找到与e中不同的字母并且这个单词比前一个记录的长
		{
			msize = str.size();
			maxstr = str;
		}
	}
	ifile.close();
	cout << maxstr << endl;
	return 0;
}

9.50

#include 
#include 
#include 

int stoint(const std::vector &s);
double stodouble(const std::vector &s);
int main()
{
	using namespace std;
	vector vsint;
	cout << "enter string:";
	string temp;
	while (cin >> temp)
	{
		vsint.push_back(temp);
	}
	int sum = stoint(vsint);
	cout << sum << endl;
	vector vsdouble;
	cout << "enter string:";
	cin.clear();
	while (cin >> temp)
	{
		vsdouble.push_back(temp);
	}
	double dt = stodouble(vsdouble);
	cout << dt << endl;
	system("pause");
	return 0;
}
int stoint(const std::vector &s)
{
	int sum = 0;
	for (auto &x:s)
	{
		sum += stoi(x);
	}
	return sum;
}
double stodouble(const std::vector &s)
{
	double sum = 0;
	for (auto &x : s)
	{
		sum += stoi(x);
	}
	return sum;
}

9.51

#include 
#include 
#define E "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
#define N "0123456789"
#define C "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"
class data
{
	unsigned y;
	unsigned m;
	unsigned d;
public:
	data(std::string s)
	{
		if (s.find_first_of(E) == std::string::npos)		//如果不包含英文
		{
			std::string::size_type dd=0, mm=0, yy=0;
			dd = stoi(s.substr(0, s.find_first_not_of(N)));	//截取第一段、第二段、第三段
			mm = stoi(s.substr(s.find_first_not_of(N)+1, s.find_first_not_of(N) - s.find_last_not_of(N)));
			yy = stoi(s.substr(s.find_last_not_of(N) + 1));
			if (dd < 13)					//如果是以月份为头
			{
				m = dd;
				if (mm < 32)				//如果中间是日期
				{
					d = mm;
					y = yy;
				}
				else
				{
					y = mm;
					d = yy;
				}
			}
			else if (dd > 32)				//如果以年份为头
			{
				y = dd;
				if (mm < 13)				//如果中间是月份
				{
					m = mm;
					d = yy;
				}
				else
				{
					d = mm;
					m = yy;
				}
			}
			else						//否则就是以日期为头
			{
				d = dd;
				if (mm < 13)				//如果中间是月份
				{
					m = mm;
					y = yy;
				}
				else
				{
					m = yy;
					y = mm;
				}
			}
		}
		else
		{
			std::string::size_type f, l, a, b;
			std::string temp1 = s.substr(f = s.find_first_of(E), l = s.find_last_of(E)+1);//截取英文部分
			if (f == 0)					//如果以因为为头
			{
				a = stoi(s.substr(l+1, s.find_last_not_of(N)));
				b = stoi(s.substr(s.find_last_not_of(N) + 1));
			}
			else if (s.find_last_not_of(C) + 1 == f)	//如果以英文结尾
			{
				a = stoi(s.substr(0, s.find_first_not_of(N)));
				b = stoi(s.substr(s.find_first_not_of(N) + 1, s.find_last_of(N)));
			}
			else						//以英文在中间
			{
				a = stoi(s.substr(0, s.find_first_not_of(N)));
				b = stoi(s.substr(s.find_last_not_of(N) + 1));
			}						//判断月份
			if (s.find("Jan") != std::string::npos)  m = 1;
			if (s.find("Feb") != std::string::npos)  m = 2;
			if (s.find("Mar") != std::string::npos)  m = 3;
			if (s.find("Apr") != std::string::npos)  m = 4;
			if (s.find("May") != std::string::npos)  m = 5;
			if (s.find("Jun") != std::string::npos)  m = 6;
			if (s.find("Jul") != std::string::npos)  m = 7;
			if (s.find("Aug") != std::string::npos)  m = 8;
			if (s.find("Sep") != std::string::npos)  m = 9;
			if (s.find("Oct") != std::string::npos)  m = 10;
			if (s.find("Nov") != std::string::npos)  m = 11;
			if (s.find("Dec") != std::string::npos)  m = 12;
			if (a < 32)					//判断日期与年份
			{
				d = a;
				y = b;
			}
			else
			{
				d = b;
				y = a;
			}
		}
	}
	friend std::ostream &operator<<(std::ostream &os, const data &d)
	{
		os << d.y << "/" << d.m << "/" << d.d << "\n";
		return os;
	}
};
int main()
{
	using namespace std;
	string temp;
	cout << "enter data:";
	getline(cin, temp);
	data time(temp);
	cout << time << endl;
	system("pause");
	return 0;
}

9.52

表示看不懂题目










......好吧,看了几遍于是有点头目

大概意思是把一个字符串里的括号(包含括号,不管什么内容)的内容替换为指定内容

一个栈stack sc;要把"aaa a(a(ds)d(sd))aa aa(aaaa(aaa((a)aa)s))aa"用替换掉,例:变成aaa a#aa aa#aa

#include 
#include 
#include 
int main()
{
	using namespace std;
	string str;
	getline(cin, str);
	int s = 0;
	stack sc;
	for (auto x : str)
	{
		sc.push(x);
		if (x == '(')				
			++s;				//记录'('出现的次数
		if (x == ')'&&s)			//如果之前出现过'('和现在是')'
		{
			while (sc.top() != '(')		//弹出刚刚加入的元素,一直到'(',相当于删除了"***)"括号
				sc.pop();			
			sc.pop();			//删除'('
			sc.push('@');			//插入@标记表示这里删除过
			--s;
		}
	}
	string st;
	while (!sc.empty())				//如果sc不为空
	{						//把sc的内容全部复制到st并删除sc所有的内容
		st.insert(st.begin(), sc.top());//把最后一个内容弹出并插入到st的最前面
		sc.pop();				//弹出并删除刚刚弹出的内容
	}
	cout << st << endl;
	system("pause");
	return 0;
}





OK,复习完











你可能感兴趣的:(c++primer第五版练习,c++,c++prmer)