C ++ Primer (第五版) 第九章习题练习

本文详细讲解了C++中list, deque和vector在插入、删除操作中的适用场景,并提供了示例代码,涉及迭代器操作、数据插入、查找与替换等。重点讨论了forward_list的特性与与其他容器的插入删除区别。
摘要由CSDN通过智能技术生成

学习笔记所用
本文部分内容参考了:C++Primer第五版——习题答案+详解(完整版)
9.1

a: 用list或者forward_list,因为要在中间插入元素。
b: 用deque,因为要在头部和尾部进行删除和插入操作
c: 用vector

9.2

list<deque<int>> L1;

9.3

1: 它们指向同一个容器中的元素,或者容器中最后一个元素之后的位置。
2: begin要在end之前,即end可以等于但不能小于begin。

9.4

bool cz(vector<int>::iterator ibeg, vector<int>::iterator iend, int x) {
    while (ibeg != iend) {
        if (*ibeg == x) return true;
        ibeg++;
    }
    return false;
}

9.5

vector<int>::iterator cz(vector<int>::iterator ibeg, vector<int>::iterator iend, int x) {
    while (ibeg != iend) {
        if (*ibeg == x) return ibeg;
        ibeg++;
    }
    return iend;
}

9.6

while的判断条件应该改为(iter1!=iter2),并且要保证iter1往后走。

9.7

vector<int>::iterator

9.8

读取:list<string>::const_iterator
写入:list<string>::iterator

9.9

begin函数是被重载过的。cbegin不能对对象执行修改或删除操作。

9.10

it1: vector<int>::iterator
it2: const vector<int>::iterator
it3: vector<int>::const_iterator
it4: const vector<int>::const_iterator

9.11

 vector<int> a;//a为空
 vector<int> a=b;//a和b一样
 vector<int> a = {1,3,5};//a初始化为1,3,5
 vector<int> a(5,1);//a初始化为5个1
 vector<int> a(5);//a初始化为5个0
 vector<int> a(b.begin(), b.begin()+2);//a初始化为b的前两个元素,其中b类型可以不和a一样

9.12

主要后者可以接受与带构造类型不同的变量。
也可以决定范围。

9.13

#include <iostream>
#include <vector>
#include <list>
#include <array>
using namespace std;

int main()
{
    list <int> b = { 1,2,3,4,5 };
    vector<int> c = { 6,7,8,9,10 };
    vector<double> a1(b.begin(), b.end());
    for (auto i : a1) {
        cout << i << " ";
    }
    vector<double> a2(b.begin(), b.end());
    for (auto i : a2) {
        cout << i << " ";
    }
    return -1;
}

9.14

#include <iostream>
#include <vector>
#include <list>
#include <array>
using namespace std;

int main()
{
    list<string> names;
    vector<const char*> oldstyle;
    names.assign(oldstyle.begin(), oldstyle.end());
    return -1;
}

9.15

bool pd(vector<int> a, vector<int> b) {
    if (a == b) return true;
    return false;
}

9.16

bool pd(list<int> a, vector<int> b) {
    vector<int> c(a.begin(), a.end());
    if (c == b) return true;
    return false;
}

9.17

c1和c2的容器类型和元素类型都要一致

9.18

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

int main()
{
    deque<string> ds;
    string s;
    while (cin>>s)
    {
        ds.push_back(s);
    }
    for (auto i : ds) {
        cout << i << endl;
    }
    return -1;
}

9.19

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

int main()
{
    list<string> ds;
    string s;
    while (cin>>s)
    {
        ds.push_back(s);
    }
    for (auto i : ds) {
        cout << i << endl;
    }
    return -1;
}

9.20

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

int main()
{
    list<int> la = {1,2,3,4,5,6,7,8,9,10};
    deque<int> di1,di2;
    for (auto i : la) {
        if (i % 2 == 0) {
            di1.push_back(i);
        }
        else {
            di2.push_front(i);
        }
    }
    for (auto i : di1) {
        cout << i << " ";
    }
    cout << endl;
    for (auto i : di2) {
        cout << i << " ";
    }
    return -1;
}

9.21

每次插入,之后的所有元素都要往后边移动,时间复杂度为O(n)

9.22

如果第一个值不等于some_val,会进入死循环,iter没有往后移动

9.23

4个值一样

9.24

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

int main()
{
    vector<int> la = {1,2,3,4,5,6,7,8,9,10};
    cout << la.at(0) << endl;
    cout << la[0] << endl;
    cout << *la.begin() << endl;
    cout << la.front() << endl;
    return -1;
}

9.25

相等:将一个元素也不删除;
如果elem2是尾后迭代器:将会删除从elem1之后的所有元素。
如果两个都是尾后迭代器:不删除任何元素。

9.26

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

int main()
{
    int ia[] = { 0,1,1,2,3,5,8,13,21,55,89 };
    vector<int> vi;
    list<int> li;
    for (auto i : ia) {
        vi.push_back(i);
        li.insert(li.end(),i);
    }
    for (auto i = vi.begin(); i != vi.end(); ) {
        if (*i % 2 == 0) {
            i = vi.erase(i);
        }
        else {
            ++i;
        }
    }
    for (auto i = li.begin(); i != li.end(); i) {
        if (*i % 2 == 1) {
            i = li.erase(i);
        }
        else {
            i++;
        }
    }
    for (auto i:vi) {
        cout << i << " ";
    }
    cout << endl;
    for (auto i:li) {
        cout << i << " ";
    }
    cout << endl;
    return -1;
}

9.27

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

int main()
{
    forward_list<int>ia = { 0,1,1,2,3,5,8,13,21,55,89 };
    auto pre = ia.before_begin(), p = ia.begin();
    while (p != ia.end()) {
        if (*p % 2 == 1) {
            p = ia.erase_after(pre);
        }
        else {
            pre = p;
            ++p;
        }
    }
    for (auto i : ia) {
        cout << i << " ";
    }
    return -1;
}

9.28

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

void cr(forward_list<string>&fls, string s1, string s2) {
    auto pre= fls.before_begin(),p = fls.begin();
    while (p != fls.end()) {
        if (*p == s1) {
            fls.insert_after(p, s2);
            break;
        }
        else {
            pre = p;
            ++p;
        }
    }
    if (p == fls.end()) {
        fls.insert_after(pre, s2);
    }
}

int main()
{
    forward_list<string>fls = { "1234","dadad","xccxz" };
    string s1 = "1234", s2 = "9999";
    cr(fls, s1, s2);
    for (auto i : fls) {
        cout << i << endl;
    }
    return -1;
}

总结一下forward_list与其他容器插入和删除后返回指针的区别

forward_list其余顺序容器
insert返回一个指向最后一个插入元素的迭代器返回指向新添加的第一个元素的迭代器
erase返回一个指向被删元素之后的迭代器返回一个指向被删元素之后的迭代器

9.29

1.将在后边添加7502.将删稠后边的90个元素。

9.30

元素类型必须可以进行初始化。如果是类类型元素,则该类必须有一个默认构造函数。

9.31

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

//forward_list
int main()
{
    forward_list<int> vi = { 0,1,2,3,4,5,6,7,8,9 };
    auto pre = vi.before_begin(),iter = vi.begin();
    while (iter != vi.end()) {
        if (*iter % 2) {
            vi.insert_after(pre, *iter);
            pre = iter;
            iter++;
        }
        else {
            iter = vi.erase_after(pre);
        }
    }
    for (auto i : vi) {
        cout << i << " ";
    }
    return -1;
}
//list
int main()
{
    list<int> 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++;//这点不同,因为list没有+=操作
            iter++;
        }
        else {
            iter = vi.erase(iter);
        }
    }
    for (auto i : vi) {
        cout << i << " ";
    }
    return -1;
}

9.32

如果iter+=2也改为iter++,就合法,否则不合法。

9.33

无限循环。

9.34

无限循环

9.35

size():是当前元素个数。
capacity():是可存储元素个数。

9.36

不可能。

9.37

这两种都属于链式结构,只要电脑有空间,它就可以添加元素,所以没有该函数。

9.39

最后svec如果包括k个元素,则可以存储k+k/2个元素。

9.40

capacity:
256:384
512:768
1000:1500
1048:1536

9.41

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

int main(int argc, char** argv)
{
	vector<char> vc = { 'a','b', 'c', 'd', 'e' };
	string s1(vc.begin(),vc.end());
	cout << s1;
	return 0;
}

9.42

预先分配足够的空间,防止加入元素后需要进行扩充空间。

9.43

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

void th(string& s, const string oldVal, const string newVal) {
	int olen = oldVal.size(), nlen = newVal.size();
	for (int i = 0; i < s.size() - olen + 1; i++) {
		string s1 = s.substr(i, olen);
		if (s1 == oldVal) {
			s.replace(i, olen, newVal);
			i =i + nlen - 1;
		}		
	}
}

int main(int argc, char** argv)
{
	string s = "ada,tho,thru,tho,tho,thru,tho,adsda,tho,thru,thru,thru";
	string oldVal = "tho", newVal = "though";
	th(s, oldVal, newVal);
	cout << s << endl;
	oldVal = "thru";
	th(s, oldVal, newVal);
	cout << s << endl;
	return 0;
}

运行结果:
9.44

如上题所示。

9.45

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

void th(string& s, const string pre, const string post) {
	s.insert(s.begin(), pre.begin(), pre.end());
	s.append(post.begin(), post.end());
}

int main(int argc, char** argv)
{
	string s = "Gu";
	string pre = "Mr.", post = "Jr.";
	th(s, pre, post);
	cout << s;
	return 0;
}

9.46

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

void th(string& s, const string pre, const string post) {
	s.insert(0, pre, 0, pre.size());
	s.insert(s.size(), post, 0, post.size());
}

int main(int argc, char** argv)
{
	string s = "Gu";
	string pre = "Mr.", post = "Jr.";
	th(s, pre, post);
	cout << s;
	return 0;
}

9.47

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

//查找s中的每个数字字符
void f1(string& s, const string numbers) {
	for (int pos = 0; pos < s.size(); ++pos) {
		pos = s.find_first_of(numbers,pos);
		cout << s[pos] << " ";
	}
}
//查找s中的每个字母字符
void f2(string& s, const string numbers) {
	cout << endl;
	for (int pos = 0; pos < s.size(); ++pos) {
		pos = s.find_first_not_of(numbers, pos);
		if (pos < 0) break;
		cout << s[pos] << " ";
	}
}

int main(int argc, char** argv)
{
	string s = "ab2c3d7R4E6",numbers="0123456789";
	f1(s, numbers);
	f2(s, numbers);
	return 0;
}

9.48

返回2

9.49

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;


void f1(vector<string>& vs, const string numbers) {
	string maxs;
	for (int i = 0; i < vs.size(); i++) {
		int pos = vs[i].find_first_of(numbers);
		if (pos < 0) {
			if (maxs.size() < vs[i].size())
				maxs = vs[i];
		}
	}
	cout << maxs;
}

int main(int argc, char** argv)
{
	vector<string> vs = {"ac","cd","mno","rs","uvwx" };
	string numbers = "bdfghjklpqty";
	f1(vs, numbers);
	return 0;
}

9.50

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

int main(int argc, char** argv)
{
	vector<string> vs = { "4654.24","1132.35","87987.51" };
	int isum = 0;
	double dsum=0.0;
	for (int i = 0; i < vs.size(); i++) {
		int is = stoi(vs[i]);
		double ds = stod(vs[i]);
		isum += is;
		dsum += ds;
	}
	
	cout << isum << endl;
	cout << dsum;
	return 0;
}

9.51

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

class rq {
private:
	unsigned int year;
	unsigned int month;
	unsigned int data;
public:
	rq() {};
	rq(string s);
	inline void sc() {
		cout << this->year << " " << this->month << " " << this->data;
	}
};

inline
rq::rq(string s) {
	int flag = 3;
	int pos;
	string members = "0123456789";
	pos = s.find(',');
	if (pos >= 0) flag = 1;//证明是第一种情况
	else {
		pos = s.find('/');
		if (pos >= 0) flag = 2;//证明是第二种情况
	}
	switch (flag) {
	case 1:{
			string smonth = s.substr(0,s.find_first_of(members));
			int imonth;
			if (smonth == "January ") imonth = 1;
			if (smonth == "February ") imonth = 2;
			if (smonth == "March ") imonth = 3;
			if (smonth == "April ") imonth = 4;
			if (smonth == "May ") imonth = 5;
			if (smonth == "June ") imonth = 6;
			if (smonth == "July ") imonth = 7;
			if (smonth == "August ") imonth = 8;
			if (smonth == "September ") imonth = 9;
			if (smonth == "October ") imonth = 10;
			if (smonth == "November ") imonth = 11;
			if (smonth == "December ") imonth = 12;

			this->month = imonth;
			this->data = stoi(s.substr(s.find_first_of(members)));
			this->year = stoi(s.substr(s.find(',') + 1));
	}
		break;
	case 2: {
			this->month = stoi(s.substr(0));
			this->data = stoi(s.substr(s.find_first_of('/') + 1));
			this->year = stoi(s.substr(s.find_last_of('/') + 1));
	}
		  break;
	case 3:
			string smonth = s.substr(0, s.find_first_of(members));
			int imonth;
			if (smonth == "Jan ") imonth = 1;
			if (smonth == "Feb ") imonth = 2;
			if (smonth == "Mar ") imonth = 3;
			if (smonth == "Apr ") imonth = 4;
			if (smonth == "May ") imonth = 5;
			if (smonth == "Jun ") imonth = 6;
			if (smonth == "Jul ") imonth = 7;
			if (smonth == "Aug ") imonth = 8;
			if (smonth == "Sep ") imonth = 9;
			if (smonth == "Oct ") imonth = 10;
			if (smonth == "Nov ") imonth = 11;
			if (smonth == "Dec ") imonth = 12;

			this->month = imonth;
			int pos = s.find_first_of(members);
			this->data = stoi(s.substr(pos));
			++pos;
			int d_pos = pos;
			pos = s.find_first_of(members);
			if (d_pos == pos) pos++;//日是两位数
			this->year = stoi(s.substr(pos+1,s.size()-pos));
	}
}

int main(int argc, char** argv)
{
	rq t1("August 1, 1900"),t2("1/1/1990"),t3("Jan 1 1900");
	t1.sc();
	cout << endl;
	t2.sc();
	cout << endl;
	t3.sc();
	return 0;
}

9.52

文中问题描述不是很清楚,不知道是不是括号匹配问题,如果是,用一个栈就可以实现。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值