C++primer第五版第十章学习笔记

从这一章开始,不写知识点了,写点课后习题的答案吧。

练习10.1 头文件algorithm中定义了一个名为count的函数,它类似find,接受一对迭代器和一个值作为参数。count返回给定值在序列中出现的次数。编写程序,读取int序列存入vector中,打印有多少个元素的值等于给定值。

#include 
#include 
#include 
#include 
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::ifstream;
using std::cout;

int main(int argc, char *argv[])
{
	ifstream in(argv[1]);
	if(!in){
		cout<<"Open input file failed."<vi;
	int val;
	while(in>>val)
		vi.push_back(val);

	cout<<"Please input the number you want find: ";
	cin>>val;
	cout<<"There are(is) "<
main函数用了命令行参数,可以自己改成不使用命令行参数的。


练习10.2 重做上一题,但读取string序列存入list中。

#include 
#include 
#include 
#include 
#include 
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::ifstream;
using std::list;
using std::cout;

int main(int argc, char *argv[])
{
	ifstream in(argv[1]);
	if(!in){
		cout<<"Open input file failed."< ls;
	string word;
	while(in>>word)
		ls.push_back(word);

	cout<<"Please input the string you want find: ";
	cin>>word;
	cout<<"There are(is) "<


练习10.3 使用accumulate求一个vector中的元素之和。

#include 
#include 
#include 
#include 
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::ifstream;

int main(int argc, char *argv[])
{
	ifstream in(argv[1]);
	if(!in){
		cout<<"Open input file failed."< ivec;
	while(in>>ival)
		ivec.push_back(ival);
	cout<<"Sum of vector is "<


练习10.4 假定v是一个vector,那么调用accumulate( v.cbegin(), v.cend(), 0)有何错误(如果存在的话)?

accumulate的第三个参数是和的初始值,它还决定了函数的返回类型,以及函数中使用哪个加法运算符。因此,本题中的调用是错误的,第三个参数0告知accumulate,和是整型的,使用整型加法运算符。正确的调用方法是将0.0作为第三个参数传递给accumulate.


练习10.5 在本节对名册(roster)调用equal的例子中,如果两个名册中保存的都是C风格字符串而不是string,会发生什么?

equal使用==运算符比较两个序列中的元素。string类重载了==,可比较两个字符串是否长度相等且其中元素对位相等。而C风格字符串本质是char *类型,用==比较两个char *对象,只是检查两个指针值是否相等,即地址是否相等,而不会比较其中字符是否相同。所以,只有当两个序列中的指针都指向相同的地址时,equal才会返回true,否则,即使字符串内容完全相同,也会返回false。


练习10.6 编写程序,使用fill_n将一个序列中的int值都设置为0.

#include 
#include 
#include 
#include 
using std::vector;
using std::cin;
using std::cout;
using std::endl;
using std::ifstream;
int main(int argc, char *argv[])
{
	ifstream in(argv[1]);
	if(!in){
		cout<<"Open input file failed."< vec;
	while(in>>val){
		vec.push_back(val);
		cout<

练习10.7 下面程序是否有错误?如果有,请改正。

(a) vector vec; list lst; int i;
      while(cin>>i)
          lst.push_back(i);
       copy(lst.cbegin(), lst.cend(), vec.begin());

(b) vector vec;
    vec.reserve(10);
    fill_n(vec.begin(), 10, 0);

(a)有错误,copy算法要求目标序列至少要包含与源序列一样多的元素,而此程序中,vec进行缺省初始化,它是空的,copy无法进行。可以将第三个参数改为back_inserter(vec),通过它,copy算法即可将lst中的元素拷贝插入到lst的末尾。

(b)也有错误。此时,vec仍然为空,没有任何元素。而算法又不具备向容器添加元素的能力,因此fill_n仍然失败。这里还是将第一个参数改成back_inserter(vec)来让fill_n有能力向vec添加元素。


练习10.8 本节提到过,标准库算法不会改变它们所操作容器的大小。为什么使用back_inserter不会使这一断言失效?

标准库算法根本不知道有“容器”这个东西。它们只接受迭代器参数,运行于这些迭代器之上,通过这些迭代器来访问元素。

因此,当传递给算法普通迭代器时,这些迭代器只能顺序或者随机访问容器中的元素,造成的效果就是算法只能读取元素、改变元素、移动元素,但无法添加或者删除元素。

当我们传递给算法插入器,例如back_inserter时,由于这类迭代器能调用下层容器的操作来向容器插入元素,造成算法执行的效果就是向容器中添加了元素。

标准库算法从来不直接操作容器,它们只操作迭代器,从而间接访问容器。能不能插入和删除元素,不在于算法,而在于传递给它们的迭代器是否具有这样的能力。


练习10.9 实现你自己的elimDups。测试你的程序,分别在读取输入后、调用unique后以及调用erase后打印vector的内容。

#include 
using std::cin;
using std::endl;
using std::cout;
#include 
using std::vector;
#include 
using std::string;
#include 
using std::ifstream;
#include 

inline void output_words(vector &words)
{
	for(auto iter=words.begin(); iter!=words.end(); ++iter)
		cout<<*iter<<" ";
	cout< &words)
{
	output_words(words);

	sort(words.begin(), words.end());
	output_words(words);

	auto end_unique=unique(words.begin(), words.end());
	output_words(words);

	words.erase(end_unique, words.end());
	output_words(words);
}

int main(int argc, char *argv[])
{
	ifstream in(argv[1]);
	if(!in){
		cout<<"Open input file failed."< vec;
	while(in>>word)
		vec.push_back(word);
	elimDups(vec);

	return 0;
}

练习10.10 你认为算法不改变容器大小的原因是什么?

泛型算法的一大优点是“泛型”,也就是一个算法可用于多种不同的数据结构,算法与所操作的数据结构分离。要做到算法与数据结构分离,重要的技术手段就是使用迭代器作为两者的桥梁。算法从不操作具体的容器,从而也就不存在与特定容器绑定,不适用于其他容器的问题。算法只操作迭代器,由迭代器真正实现对容器的访问。不同容器实现自己特定的迭代器,算法操作不同的迭代器就实现了对不同容器的访问。

因此,并不是算法应该改变或不改变容器的问题。为了实现与数据结构的分离,为了实现通用性,算法根本就不该知道容器的存在。算法访问数据的唯一通道是迭代器。是否改变容器大小,完全是迭代器的选择和责任。


练习10.11 编写程序,使用stable_sort和isShorter将传递给你的elimDups版本的vector排序。打印vector的内容,验证你程序的正确性。

#include 
using std::cin;
using std::endl;
using std::cout;
#include 
using std::vector;
#include 
using std::string;
#include 
using std::ifstream;
#include 

inline void output_words(vector &words)
{
	for(auto iter=words.begin(); iter!=words.end(); ++iter)
		cout<<*iter<<" ";
	cout< &words)
{
	output_words(words);

	sort(words.begin(), words.end());
	output_words(words);

	auto end_unique=unique(words.begin(), words.end());
	output_words(words);

	words.erase(end_unique, words.end());
	output_words(words);

	stable_sort(words.begin(), words.end(), isShorter);
	output_words(words);
}

int main(int argc, char *argv[])
{
	ifstream in(argv[1]);
	if(!in){
		cout<<"Open input file failed."< vec;
	while(in>>word)
		vec.push_back(word);
	elimDups(vec);

	return 0;
}

练习10.13:标准库定义了名为partition的算法,它接受一个谓词,对容器内容进行划分,是得为此为true的值会排在容器的前半部分,而使谓词为false的值会排在后半部分。算法返回一个迭代器,指向最后一个使谓词为true的元素之后的位置。编写函数,接受一个string,返回一个bool值,指出string是否有5个或更多字符。使用此函数划分words。打印出长度大于等于5的元素。

#include 
using std::string;
#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
#include 
using std::ifstream;

inline void output_words(vector::iterator beg, vector::iterator end)
{
	for(auto iter=beg; iter!=end; ++iter)
		cout<<*iter<<" ";
	cout<=5;
}
int main(int argc, char *argv[])
{
	ifstream in(argv[1]);
	if(!in){
		cout<<"Open input file failed."< vec;
	while(in>>word)
		vec.push_back(word);
	auto iter=partition(vec.begin(),vec.end(),five_or_more);
	output_words(vec.begin(),iter);
	cout<

练习10.14:编写一个lambda,接受两个int,返回它们的和。

#include 
using std::cin;
using std::cout;
using std::endl;

int main(int argc, char *argv[])
{
	auto sum=[](int a, int b){return a+b;};

	cout<

练习10.15:编写一个lambda,捕获它所在函数的int,并接受一个int参数。lambda应该返回捕获的int和int参数的和。

#include 
using std::cin;
using std::cout;
using std::endl;

void add(int a)
{
	auto sum=[a](int b){return a+b;};
	cout<


练习10.16:使用lambda编写你自己版本的biggies.

#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
using std::string;
#include 
#include 
using std::ifstream;

string make_plural(size_t ctr, const string &word, const string &ending)
{
	return (ctr>1)? word + ending: word;
}
void elimdups(vector &words)
{
	sort(words.begin(), words.end());
	auto end_unique=unique(words.begin(), words.end());
	words.erase(end_unique, words.end());
}

void biggies(vector &words, vector::size_type sz)
{
	elimdups(words);      //将words按字典序排序,删除重复词
	// 按长度排序,长度相同的单词维持字典序
	stable_sort(words.begin(), words.end(), [](const string &a, const string &b){return a.size()=sz的元素
	auto wc=find_if(words.begin(), words.end(), [sz](const string &a){return a.size()>=sz;});
	// 计算满足size()>=sz的元素的数目
	auto count=words.end()-wc;
	cout< vec;
	while(in>>str)
		vec.push_back(str);
	biggies(vec, 5);

	return 0;
}

练习10.18:重写biggies,用partition代替find_if。我们在10.3.1节练习10.13中介绍了partition算法
#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
using std::string;
#include 
#include 
using std::ifstream;

string make_plural(size_t ctr, const string &word, const string &ending)
{
	return (ctr>1)? word + ending: word;
}
void elimdups(vector &words)
{
	sort(words.begin(), words.end());
	auto end_unique=unique(words.begin(), words.end());
	words.erase(end_unique, words.end());
}

void biggies(vector &words, vector::size_type sz)
{
	elimdups(words);      //将words按字典序排序,删除重复词
	// 获取一个迭代器,指向最后一个满足size()>=sz的元素之后的位置
	auto wc=partition(words.begin(), words.end(), [sz](const string &a){return a.size()>=sz;});
	// 计算满足size()>=sz的元素的数目
	auto count=wc-words.begin();
	cout< vec;
	while(in>>str)
		vec.push_back(str);
	biggies(vec, 5);

	return 0;
}

练习10.19:用stable_partition 重写前一题的程序,与stable_sort类似,在划分后的序列中维持原有元素的顺序。

#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
using std::string;
#include 
#include 
using std::ifstream;

string make_plural(size_t ctr, const string &word, const string &ending)
{
	return (ctr>1)? word + ending: word;
}
void elimdups(vector &words)
{
	sort(words.begin(), words.end());
	auto end_unique=unique(words.begin(), words.end());
	words.erase(end_unique, words.end());
}

void biggies(vector &words, vector::size_type sz)
{
	elimdups(words);      //将words按字典序排序,删除重复词
	// 获取一个迭代器,指向最后一个满足size()>=sz的元素之后的位置
	auto wc=stable_partition(words.begin(), words.end(), [sz](const string &a){return a.size()>=sz;});
	// 计算满足size()>=sz的元素的数目
	auto count=wc-words.begin();
	cout< vec;
	while(in>>str)
		vec.push_back(str);
	biggies(vec, 5);

	return 0;
}

练习10.20:标准库定义了一个名为count_if的算法。类似find_if,此函数接受一对迭代器,表示一个输入范围,还接受一个谓词,会对输入范围中每个元素执行。count_if返回一个计数值,表示谓词有多少次为真。使用count_if重写我们程序中统计有多少单词长度超过6的部分。

#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
using std::count_if;
#include 
using std::string;
#include 
using std::ifstream;

string make_plural(size_t ctr, const string &word, const string &ending)
{
	return (ctr>1) ? word + ending : word;
}

inline void output_words(vector &words)
{
	for(auto iter=words.begin(); iter!=words.end(); ++iter)
		cout<<*iter<<" ";
	cout< &words, vector::size_type sz)
{
	output_words(words);
	auto bc=count_if(words.begin(), words.end(), [sz](const string &a){return a.size()>=sz;});
	cout< vec;
	while(cin>>str)
		vec.push_back(str);
	biggies(vec,6);

	return 0;
}

练习10.21:编写一个lambda,捕获一个局部int变量,并递减变量值,直至它变为0.一旦变为0,再调用lambda应该不再递减变量。lambda应该返回一个bool值,指出捕获的变量是否为0.

#include 
using std::cin;
using std::cout;
using std::endl;
#include 

void mutable_lambda(void)
{
	int i=5;
	auto f=[i]() mutable->bool {if(i>0) {--i; return false;} else return true;};

	for(int j=0; j<6; ++j)
		cout<

练习10.22:重写统计长度小于等于6的单词数量的程序,使用函数代替lambda。

#include 
#include 
#include 
#include 
#include 
#include 
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::ifstream;
using std::bind;
using std::placeholders::_1;

string make_plural(size_t ctr, const string &word, const string &ending)
{
	return (ctr>1)? word + ending: word;
}

inline void output_words(vector &words)
{
	for(auto iter=words.begin(); iter!=words.end(); ++iter)
		cout<<*iter<<" ";
	cout<=sz;
}

auto check6=bind(check_size, _1, 6);

void biggies(vector &words, vector::size_type sz)
{
	output_words(words);
	auto bc=count_if(words.begin(), words.end(), bind(check_size, _1, sz));
	cout< vec;
	while(in>>str)
		vec.push_back(str);
	biggies(vec, 6);
	return 0;
}
练习10.23:bind接受几个参数?

bind是可变参数的。它接受的第一个参数是一个可调用对象,即实际工作函数A,返回供算法使用的新的可调用对象B。若A接受x个参数,则bind的参数个数应该是x+1,即除了A外,其他参数应一一对应A所接受的参数。这些参数中有一部分来自于B(_n),另外一些来自于所处函数的局部变量。


练习10.24:给定一个string,使用bind和check_size在一个int的vector中查找第一个大于string长度的值。

#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::string;
#include 
using std::vector;
#include 
using std::placeholders::_1;
#include 

bool check_size(const string &s, int sz)
{
	return s.size() &vc, const string &s)
{
	// 查找第一个大于等于s长度的数值
	auto p=find_if(vc.begin(), vc.end(), bind(check_size, s, _1));
	// 打印结果
	cout<<"第"< vc={1,2,3,4,5,6,7,8,9};
	biggies(vc,"hello");
	biggies(vc,"everyone");
	biggies(vc,"!");
	
	return 0;
}

练习10.25:在10.3.2节的练习中,编写了一个使用partition的biggies版本。使用check_size和bind重写此函数。

#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
using std::string;
#include 
#include 
using std::placeholders::_1;
#include 
using std::ifstream;

bool check_size(const string &s, string::size_type sz)  
{  
    return s.size() >= sz;  
} 
 
void elimDups(vector &words)
{
	sort(words.begin(), words.end());
	auto end_unique=unique(words.begin(), words.end());
	words.erase(end_unique, words.end());
}

string make_plural(size_t ctr, const string &word, const string &ending)  
{  
    return (ctr > 1) ? word + ending : word;  
}  

void biggies(vector &words, vector::size_type sz)
{
	elimDups(words); 
	for_each(words.begin(), words.end(), [](const string &s){cout << s << " "; }); 
	cout< vec;
	while(in>>word)
		vec.push_back(word);
	biggies(vec,6);
	return 0;
}

练习10.26:解释三种插入迭代器的不同之处。

三者的差异在于如何向容器插入元素:back_inserter调用push_back,front_inserter 调用push_front,inserter则调用inserter。这决定了它们插入元素位置的不同。back_inserter总是插入到容器尾元素之后,front_inserter 总是插入到元素首元素之前,而inserter则是插入到给定位置之前。


练习10.27:除了unique之外,标准库还定义了名为unique_copy的函数,它接受第三个迭代器,表示拷贝不重复元素的目的位置。编写一个程序,使用unique_copy将一个vector中不重复的元素拷贝到一个初始为空的list中。

#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
#include 
using std::list;
#include 
using std::inserter;

int main(int argc, char *argv[])
{
	vector vi={1,2,2,3,4,5,5,6};
	list li;

	unique_copy(vi.begin(), vi.end(), back_inserter(li));
	for_each(li.begin(), li.end(), [](const int &i){cout << i << " "; }); 
	cout<

练习10.28:一个vector中保存1到9共9个值,将其拷贝到三个其他容器中。分别使用inserter、back_inserter 和front_inserter将元素添加到三个容器中。对每种 inserter,估计输出序列是怎样的,运行程序验证你的估计是否正确。

#include 
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
using std::list;
#include 
#include 
using std::inserter;

int main(int argc, char *argv[])
{
	vector vec={1,2,3,4,5,6,7,8,9};
	list lst1,lst2,lst3;
	unique_copy(vec.begin(), vec.end(), front_inserter(lst1));
	unique_copy(vec.begin(), vec.end(), back_inserter(lst2));
	unique_copy(vec.begin(), vec.end(), inserter(lst3,lst3.begin()));
	for_each(lst1.begin(), lst1.end(), [](const int &i){cout<

练习10.29:编写程序,使用流迭代器读取一个文本文件,存入一个vector中的string里。

#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::ifstream;
#include 
using std::vector;
#include 
using std::string;
#include 
using std::istream_iterator;
using std::ostream_iterator;
#include 

int main(int argc, char *argv[])
{
	ifstream in(argv[1]);
	if(!in){
		cout<<"Open input file failed."< str_it(in);
	// 尾后迭代器
	istream_iterator eof;
	vector svec;
	while(str_it!=eof)
		svec.push_back(*str_it++);
	ostream_iterator out_iter(cout," ");
	copy(svec.begin(),svec.end(),out_iter);
	return 0;

}

练习10.30:使用流迭代器、sort和copy从标准输入读取一个整数序列,将其排序,并将结果写到标准输出。

#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
#include 
using std::istream_iterator;
using std::ostream_iterator;

int main(int argc, char *argv[])
{
	istream_iterator int_it(cin), eof;
	vector vec;
	while(int_it!=eof)
		vec.push_back(*int_it++);
	sort(vec.begin(), vec.end());
	ostream_iterator out_iter(cout, " ");
	copy(vec.begin(), vec.end(), out_iter);
	
	return 0;

}
练习10.31:修改前一题的程序,使其只打印不重复元素。你的程序应使用unique_copy。

#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
#include 
using std::istream_iterator;
using std::ostream_iterator;

int main(int argc, char *argv[])
{
	istream_iterator int_it(cin), eof;
	vector vec;
	while(int_it!=eof)
		vec.push_back(*int_it++);
	sort(vec.begin(), vec.end());
	ostream_iterator out_iter(cout, " ");
	unique_copy(vec.begin(), vec.end(), out_iter);

	return 0;

}

练习10.33:编写程序,接受三个参数:一个输入文件和两个输出文件的文件名。输入文件保存的应该是整数。使用istream_iterator读取输入文件。使用ostream_iterator将奇数写入第一个输出文件,每个值之后都跟一个空格。将偶数写入第二个输出文件,每个值独占一行。

#include 
using std::endl;
using std::cout;
#include 
using std::istream_iterator;
using std::ostream_iterator;
#include 
using std::string;
#include 
#include 
using std::ifstream;
using std::ofstream;

int main(int argc, char *argv[])
{
    if(argc!=4){
        cout<<"用法: exercise.exe in_file out_file1 out_file2"< in_iter(in);
    // 尾后迭代器
    istream_iterator eof;
    // 第一个输出文件以空格间隔整数
    ostream_iterator out_iter1(out1, " ");
    // 第二个输出文件一换行间隔整数
    ostream_iterator out_iter2(out2, "\n");
    while(in_iter!=eof){
        if(*in_iter%1)     //奇数写入第一个文件         
            *out_iter1++= *in_iter;
        else               //偶数写入第二个文件
            *out_iter2++= *in_iter;
        ++in_iter;
    }

    return 0;
}

练习10.34:使用reserve_iterator逆序打印一个vector。

#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
using std::ostream_iterator;
#include 
#include 
using std::ifstream;

int main(int argc, char *argv[])
{
	if(argc!=2){
		cout<<"用法:exercise.exe in_file"< vec;
	while(in>>val)     //从文件中读取整数
		vec.push_back(val);
	ostream_iterator out_it(cout, " ");
	copy(vec.rbegin(),vec.rend(),out_it);

	return 0;
}

练习10.35:使用普通迭代器逆序打印一个vector。

#include 
using std::cin;
using std::cout;
using std::endl;
#include 
using std::vector;
#include 
#include 
#include 
using std::ifstream;

int main(int argc, char *argv[])
{
	if(argc!=2){
		cout<<"用法:exercise.exe in_file"< vec;
	while(cin>>val)
		vec.push_back(val);
	for(vector::iterator it=vec.end(); it!=vec.begin();)
		cout<<*(--it)<<" ";
	cout<

练习10.36:使用find在一个int的list中查找最后一个值为0的元素。

#include 
#include 
#include 
#include 

using namespace std;

int main(int argc, char *argv[])
{
	list li = { 1, 1, 2, 3, 5, 8, 0, 13, 13, 26, 0, 39 };
	// 利用反向迭代器查找最后一个0
	auto last_z = find(li.rbegin(), li.rend(), 0);
	// 将迭代器向链表头方向推进一个位置
	// 转换为普通迭代器时,将回到最后一个0的位置
	++last_z;
	int p=1;
	// 用base将last_z转换为普通迭代器
	// 从链表头开始遍历,计数最后一个0的编号
	for(auto iter=li.begin(); iter!=last_z.base(); ++iter,++p);

	if(p>=li.size())   //未找到0
		cout<<"容器中没有0"<

练习10.37:给定一个包含10个元素的vector,将位置3到7之间的元素按逆序拷贝到一个list中。

#include   
#include   
#include   
#include   
#include   
  
using namespace std;  
  
int main(int argc, char *argv[])  
{  
  
    vector vi = { 0, 1 ,2, 3, 4, 5, 6, 7, 8, 9};  
    ostream_iterator out_iter(cout, " ");  
    // 用流迭代器和copy输出int序列
    copy(vi.begin(), vi.end(), out_iter);  
    cout << endl;  
  
    list li;
    //将vi[2],也就是第3个元素的位置转换为反向迭代器
    vector::reverse_iterator re(vi.begin()+2);
    // 将vi[7],也就是第8个元素的位置转换为反向迭代器
    vector::reverse_iterator rb(vi.begin()+7);
    // 用反向迭代器将元素逆序拷贝到list
    copy(rb, re, back_inserter(li));
    copy(li.begin(), li.end(), out_iter);
    cout<

练习10.38:列出5个迭代器类别,以及每类迭代器所支持的操作。

输入迭代器:只读,不写;单遍扫描,只能递增;还支持相等性判定运算符(==、!=)、解引用运算符(*)和箭头运算符(->)。

输出迭代器:只写,不读;单遍扫描,只能递增,支持解引用运算符。

前向迭代器:可读写;多遍扫描,只能递增,支持所有输入、输出迭代器的操作。

双向迭代器:可读写;多遍扫描,可递增递减,支持所有前向迭代器操作。

随机访问迭代器:可读写,多遍扫描,支持全部迭代器运算。


练习10.39:list上的迭代器属于哪类?vector呢?

list上的迭代器是双向迭代器,vector上的迭代器是随机访问迭代器。


练习10.40:你认为copy要求哪类迭代器?reverse和unique呢?

copy要求前两个参数至少是输入迭代器,表示一个输入范围。它读取这个范围中的元素,写入到第三个参数表示的输出序列中,因此第三个参数至少是输出迭代器。

reverse要反向处理序列,因此它要求两个参数至少是双向迭代器。

unique顺序扫描元素,覆盖重复元素,因此要求两个参数至少是前向迭代器。

“至少”意味着能力更强的迭代器是可以接受的。


练习10.41:仅根据算法和参数的名字,描述下面每个标准库算法执行什么操作:

replace(beg, end, old_val, new_val);
replace_if(beg, end, pred, old_val, new_val);
replace_copy(beg, end, dest, old_val, new_val);
replace_copy_if(beg, end, dest, pred, new_val);
1.将范围[beg, end)间值等于old_val的元素替换为new_val;

2.将范围[beg, end)间满足谓词pred的元素替换为new_val;

3.将范围[beg, end)间的元素拷贝到目的序列dest中,将其中值等于old_val的元素替换为new_val;

4.将范围[beg, end)间的元素拷贝到目的序列dest中,将其中满足谓词pred的元素替换为new_val;


练习10.42:使用list代替vector重新实现10.2.3节中的去除重复单词的程序。

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

inline void output_words(list &words)
{
	for(auto iter=words.begin(); iter!=words.end(); ++iter)
		cout<<*iter<<" ";
	cout< &words)
{
	output_words(words);

	words.sort();
	output_words(words);

	words.unique();
	output_words(words);  
}

int main(int argc, char *argv[])
{
	ifstream in(argv[1]);
	if(!in){
		cout<<"Open input file failed."< words;
	string word;
	while(in>>word)
		words.push_back(word);

	elimDups(words);
	return 0;
}


你可能感兴趣的:(C++primer第五版第十章学习笔记)