第十章 泛型算法

练习10.1

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

解:

#include <iostream>
#include <list>
#include <deque>
#include <vector>
#include <forward_list>
#include <string>
#include <algorithm>
#include <fstream>
#include <numeric>using namespace std;int main()
{vector<int> vi;int val;while (cin >> val)vi.push_back(val);cout << "请输入要搜索的数值" << endl;cin >> val;cout << "序列中有" << count(vi.begin(), vi.end(), val) << "个" << endl;return 0;
}

练习10.2

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

解:

#include <iostream>
#include <list>
#include <deque>
#include <vector>
#include <forward_list>
#include <string>
#include <algorithm>
#include <fstream>
#include <numeric>using namespace std;int main()
{vector<int> vi;string val;while (cin >> val)vi.push_back(val);cout << "请输入要搜索的数值" << endl;cin >> val;cout << "序列中有" << count(vi.begin(), vi.end(), val) << "个" << endl;return 0;
}

练习10.3

accumulate求一个 vector<int> 中元素之和。

解:

#include <iostream>
#include <list>
#include <deque>
#include <vector>
#include <forward_list>
#include <string>
#include <algorithm>
#include <fstream>
#include <numeric>using namespace std;int main()
{vector<int> vi;int val;while (cin >> val)vi.push_back(val);cout << accumulate(vi.begin(), vi.end(), 0) << endl;return 0;
}

练习10.4

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

解:
accumulate第三个参数是和的初值,它还决定了函数的返回类型,以及函数中使用哪个加法类型
因此,本题中告诉编译器是整型,但是实际上却是浮点型,正确应该用0.0

练习10.5

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

C风格字符串是用指向字符的指针表示的,因此会比较两个指针的值(地址),而不会比较这两个字符串的内容。

练习10.6

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

解:

#include <iostream>
#include <deque>
#include <vector>
#include <string>
#include <algorithm>using namespace std;int main()
{vector<int> vi;int val;while (cin >> val)vi.push_back(val);for (auto item : vi) cout << item << " ";cout << endl;fill_n(vi.begin(), vi.size(), 0);for (auto iter = vi.begin(); iter != vi.end(); iter ++ )cout << *iter << " ";return 0;
}

练习10.7

下面程序是否有错误?如果有,请改正:

(a) vector<int> vec; list<int> lst; int i;while (cin >> i)lst.push_back(i);copy(lst.cbegin(), lst.cend(), vec.begin());
(b) vector<int> vec;vec.reserve(10);fill_n(vec.begin(), 10, 0);

解:

  • (a) 应该加一条语句 vec.resize(lst.size())copy时必须保证目标目的序列至少要包含与输入序列一样多的元素。但是copy并不会改变容器大小,因此vec还是空,所以copy无法进行
  • (b) reserve分配了足够的空间,但是不会创建新元素,所以此时vec任然为孔。算法可能改变容器中保存的元素的值,也可能在容器内移动元素,永远不会直接添加和删除元素(c++ priemr中文版第五版 P338),所以此处应该改为resize(10)。

练习10.8(*)

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

back_inserter 是插入迭代器,在 iterator.h 头文件中,不是标准库的算法。

~~~   严格来说,标准库算法根本不知道有“容器”这个东西。它们只接受迭代器参数,运行于这些迭代器之上,通过这些迭代器访问元素。
~~~   因此,当你传递给算法普通迭代器时,这些迭代器只能顺序或随机访问容器中的元素,造成的效果就是算法只能读取元素,改变元素,移动元素,但无法添加或删除元素
~~~   但当我们传递算法插入迭代器时,例如back_inserter时,由于这类迭代器能调用下层容器的操作来向容器插入元素,造成的算法执行的效果就是向容器中添加了元素
~~~   因此,关键要理解:标准算法从来不直接操作容器,它们只操作迭代器,从而间接访问容器。能不能插入和删除元素,不在于算法,而在于传递给它们的迭代器是否具有这样的能力

练习10.9

实现你自己的elimDups。分别在读取输入后、调用unique后以及调用erase后打印vector的内容。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>// print containers like vector, deque, list, etc.
template<typename Sequence>
auto println(Sequence const& seq) -> std::ostream&
{for (auto const& elem : seq) std::cout << elem << " ";return std::cout << std::endl;
}auto eliminate_duplicates(std::vector<std::string> &vs) -> std::vector<std::string>&
{std::sort(vs.begin(), vs.end());println(vs);auto new_end = std::unique(vs.begin(), vs.end());println(vs);vs.erase(new_end, vs.end());return vs;
}int main()
{std::vector<std::string> vs{ "a", "v", "a", "s", "v", "a", "a" };println(vs);println(eliminate_duplicates(vs));return 0;
}

练习10.10

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

解:

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

练习10.11

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

解:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <list>// print a container like vector, deque, list, etc.
template<typename Sequence>
inline std::ostream& println(Sequence const& seq)
{for(auto const& elem : seq) std::cout << elem << " ";std::cout << std::endl;return std::cout;
}inline bool
is_shorter(std::string const& lhs, std::string const& rhs)
{return  lhs.size() < rhs.size();
}void elimdups(std::vector<std::string> &vs)
{std::sort(vs.begin(), vs.end());auto new_end = std::unique(vs.begin(), vs.end());vs.erase(new_end, vs.end());
}int main()
{std::vector<std::string> v{"1234", "1234", "1234", "Hi", "alan", "wang"};elimdups(v);std::stable_sort(v.begin(), v.end(), is_shorter);std::cout << "ex10.11 :\n";println(v);return 0;
}

练习10.12

编写名为 compareIsbn 的函数,比较两个 Sales_data 对象的isbn() 成员。使用这个函数排序一个保存 Sales_data 对象的 vector

解:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "../ch07/ex7_26.h"     // Sales_data class.inline bool compareIsbn(const Sales_data &sd1, const Sales_data &sd2)
{return sd1.isbn().size() < sd2.isbn().size();
}int main()
{Sales_data d1("aa"), d2("aaaa"), d3("aaa"), d4("z"), d5("aaaaz");std::vector<Sales_data> v{ d1, d2, d3, d4, d5 };// @note   the elements the iterators pointing to//         must match the parameters of the predicate.std::sort(v.begin(), v.end(), compareIsbn);for(const auto &element : v)std::cout << element.isbn() << " ";std::cout << std::endl;return 0;
}

练习10.13

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

解:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>using namespace std;inline void output_words(vector<string>::iterator beg, vector<string>::iterator end)
{for (auto iter = beg; iter != end; iter ++ )cout << *iter << " ";cout << endl;
}bool five_or_more(const string &str)
{return str.size() >= 5;
}int main()
{vector<string> words;string word;while (cin >> word)words.push_back(word);output_words(words.begin(), words.end());auto iter = partition(words.begin(), words.end(), five_or_more);output_words(words.begin(), iter);return 0;
}

练习10.14

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

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>using namespace std;int main()
{auto sum = [](int a, int b) {return a + b; };cout << sum(1, 1) << endl;return 0;
}

练习10.15

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

解:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>using namespace std;void add(int x)
{auto sum = [x] (int b) {return x + b; };cout << sum(1) << endl;
}int main()
{add(1);add(2);return 0;
}

练习10.16

使用 lambda 编写你自己版本的 biggies

解:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>// from ex 10.9
void elimdups(std::vector<std::string> &vs)
{std::sort(vs.begin(), vs.end());auto new_end = std::unique(vs.begin(), vs.end());vs.erase(new_end, vs.end());
}void biggies(std::vector<std::string> &vs, std::size_t sz)
{using std::string;elimdups(vs);// sort by size, but maintain alphabetical order for same size.std::stable_sort(vs.begin(), vs.end(), [](string const& lhs, string const& rhs){return lhs.size() < rhs.size();});// get an iterator to the first one whose size() is >= szauto wc = std::find_if(vs.begin(), vs.end(), [sz](string const& s){return s.size() >= sz;});// print the biggiesstd::for_each(wc, vs.end(), [](const string &s){std::cout << s << " ";});
}int main()
{// ex10.16std::vector<std::string> v{"1234","1234","1234","hi~", "alan", "alan", "cp"};std::cout << "ex10.16: ";biggies(v, 3);std::cout << std::endl;return 0;
}

练习10.17

重写10.3.1节练习10.12的程序,在对sort的调用中使用 lambda 来代替函数 compareIsbn

解:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "../ch07/ex7_26.h"     // Sales_data class.int main()
{Sales_data d1("aa"), d2("aaaa"), d3("aaa"), d4("z"), d5("aaaaz");std::vector<Sales_data> v{ d1, d2, d3, d4, d5 };std::sort(v.begin(), v.end(), [](const Sales_data &sd1, const Sales_data &sd2){return sd1.isbn().size() < sd2.isbn().size();});for(const auto &element : v)std::cout << element.isbn() << " ";std::cout << std::endl;return 0;
}

练习10.18

重写 biggies,用 partition 代替 find_if。我们在10.3.1节练习10.13中介绍了 partition 算法。

解:

见下题

练习10.19

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

解:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>// from ex 10.9
void elimdups(std::vector<std::string> &vs)
{std::sort(vs.begin(), vs.end());auto new_end = std::unique(vs.begin(), vs.end());vs.erase(new_end, vs.end());
}// ex10.18
void biggies_partition(std::vector<std::string> &vs, std::size_t sz)
{elimdups(vs);auto pivot = partition(vs.begin(), vs.end(), [sz](const std::string &s){return s.size() >= sz;});for(auto it = vs.cbegin(); it != pivot; ++it)std::cout << *it << " ";
}// ex10.19
void biggies_stable_partition(std::vector<std::string> &vs, std::size_t sz)
{elimdups(vs);auto pivot = stable_partition(vs.begin(), vs.end(), [sz](const std::string& s){return s.size() >= sz;});for(auto it = vs.cbegin(); it != pivot; ++it)std::cout << *it << " ";
}int main()
{// ex10.18std::vector<std::string> v{"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};std::cout << "ex10.18: ";std::vector<std::string> v1(v);biggies_partition(v1, 4);std::cout << std::endl;// ex10.19std::cout << "ex10.19: ";std::vector<std::string> v2(v);biggies_stable_partition(v2, 4);std::cout << std::endl;return 0;
}

练习10.20

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

解:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>using std::vector;
using std::count_if;
using std::string;// Exercise 10.20
std::size_t bigerThan6(vector<string> const& v)
{return count_if(v.cbegin(), v.cend(), [](string const& s){return s.size() > 6;});
}int main()
{// ex10.20vector<string> v{"alan","moophy","1234567","1234567","1234567","1234567"};std::cout << "ex10.20: " << bigerThan6(v) << std::endl;// ex10.21int i = 7;auto check_and_decrement = [&i]() { return i > 0 ? !--i : !i; };std::cout << "ex10.21: ";while(!check_and_decrement())std::cout << i << " ";std::cout << i << std::endl;return 0;
}

练习10.21

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

解:

//若lambda需要改变局部变量的值,需要在参数列表以后,函数体之前使用mutable关键字
//对于本题,由于lambda有两个返回语句,所以还需要显示的指定lambda的返回类型
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>using namespace std;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 << f() << " ";cout << endl;}int main()
{mutable_lambda();return 0;
}

练习10.22

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

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>using std::string;
using namespace std::placeholders;bool isLesserThanOrEqualTo6(const string &s, string::size_type sz)
{return s.size() <= sz;
}int main()
{std::vector<string> authors{ "Mooophy", "pezy", "Queequeg90", "shbling", "evan617" };std::cout << count_if(authors.cbegin(), authors.cend(), bind(isLesserThanOrEqualTo6, _1, 6));
}

练习10.23

bind 接受几个参数?

假设被绑定的函数接受 n 个参数,那么bind 接受n + 1个参数。

练习10.24

给定一个string,使用 bindcheck_size 在一个 intvector 中查找第一个大于string长度的值。

解:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::find_if;
using std::bind;
using std::size_t;auto check_size(string const& str, size_t sz)
{return str.size() < sz;
}int main()
{vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7 };string str("123456");auto result = find_if(vec.begin(), vec.end(), bind(check_size, str, std::placeholders::_1));if (result != vec.end())cout << *result << endl;elsecout << "Not found" << endl;return 0;
}

练习10.25

在10.3.2节的练习中,编写了一个使用partitionbiggies版本。使用 check_sizebind 重写此函数。

解:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>using std::string; using std::vector;
using namespace std::placeholders;void elimdups(vector<string> &vs)
{std::sort(vs.begin(), vs.end());vs.erase(unique(vs.begin(), vs.end()), vs.end());
}bool check_size(const string &s, string::size_type sz)
{return s.size() >= sz;
}void biggies(vector<string> &words, vector<string>::size_type sz)
{elimdups(words);auto iter = std::stable_partition(words.begin(), words.end(), bind(check_size, _1, sz));for_each(words.begin(), iter, [](const string &s){ std::cout << s << " "; });
}int main()
{std::vector<std::string> v{"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};biggies(v, 4);
}

练习10.26

解释三种插入迭代器的不同之处。

解:

  • back_inserter 使用 push_back
  • front_inserter 使用 push_front
  • inserter 使用 insert,此函数接受第二个参数,这个参数必须是一个指向给定容器的迭代器。元素将被插入到给定迭代器所表示的元素之前。

练习10.27

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

解:

//注意:和Unique一样,unique_copy也要求源容器中重复元素是相邻存放。
//因此,若vector未排序且重复元素未相邻存放,unique_copy就会失效,所以稳妥的方法是先对vector进行排序
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <list>using namespace std;int main()
{vector<int> vi{1, 2, 3, 4, 2, 5, 6};list<int> li;sort(vi.begin(), vi.end());unique_copy(vi.begin(), vi.end(), back_inserter(li));for (auto v : li)cout << v << ' ' ;cout << endl;return 0;
}

练习10.28(*)

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

解:

//本题还是很重要的,重点在于区分三种迭代器之间的差异
//back_inserter使用push_back
//front_inserter使用push_front
//inserter使用insert
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <list>using namespace std;int main()
{vector<int> vi{1, 2, 3, 4, 5, 6, 7, 8, 9};list<int> li1, li2, li3;unique_copy(vi.begin(), vi.end(), inserter(li1, li1.begin()));cout << "list 1:" << endl;for (auto item : li1)cout << item << ' ';cout << endl;unique_copy(vi.begin(), vi.end(), back_inserter(li2));cout << "list 2:" << endl;for (auto item : li2)cout << item << ' ';cout << endl;unique_copy(vi.begin(), vi.end(), front_inserter(li3));cout << "list 3:" << endl;for (auto item : li3)cout << item << ' ';cout << endl;cout << endl;return 0;
}

练习10.29

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

解:

//C++万能头,从此省去诸多麻烦
#include <bits/stdc++.h>using namespace std;int main()
{ifstream inpt;inpt.open("mnt.txt", ios::in);if (!inpt.is_open()){cout << "文件打开失败" << endl;return -1;}istream_iterator<string> in_iter(inpt);istream_iterator<string> eof;vector<string> words;while (in_iter != eof)words.push_back(*in_iter ++ );for (auto item : words)cout << item << " " ;inpt.close();cout << endl;return 0;
}

练习10.30

使用流迭代器、sortcopy 从标准输入读取一个整数序列,将其排序,并将结果写到标准输出。

解:

#include <bits/stdc++.h>using namespace std;int main()
{istream_iterator<int> in_iter(cin);istream_iterator<int> eof;vector<int> vi;while (in_iter != eof)vi.push_back(*in_iter ++ );sort(vi.begin(), vi.end());ostream_iterator<int> out_iter(cout, " ");copy(vi.begin(), vi.end(), out_iter);cout << endl;return 0;
}

练习10.31

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

解:

#include <bits/stdc++.h>using namespace std;int main()
{istream_iterator<int> in_iter(cin);istream_iterator<int> eof;vector<int> vi;while (in_iter != eof)vi.push_back(*in_iter ++ );sort(vi.begin(), vi.end());ostream_iterator<int> out_iter(cout, " ");unique_copy(vi.begin(), vi.end(), out_iter);cout << endl;return 0;
}

练习10.32

重写1.6节中的书店程序,使用一个vector保存交易记录,使用不同算法完成处理。使用 sort 和10.3.1节中的 compareIsbn 函数来排序交易记录,然后使用 findaccumulate 求和。

解:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <numeric>
#include "../include/Sales_item.h"int main()
{std::istream_iterator<Sales_item> in_iter(std::cin), in_eof;std::vector<Sales_item> vec;while (in_iter != in_eof)vec.push_back(*in_iter++);sort(vec.begin(), vec.end(), compareIsbn);for (auto beg = vec.cbegin(), end = beg; beg != vec.cend(); beg = end) {end = find_if(beg, vec.cend(), [beg](const Sales_item &item){ return item.isbn() != beg->isbn(); });std::cout << std::accumulate(beg, end, Sales_item(beg->isbn())) << std::endl;}
}

练习10.33

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

解:

#include <fstream>
#include <iterator>
#include <algorithm>int main(int argc, char **argv)
{if (argc != 4) return -1;std::ifstream ifs(argv[1]);std::ofstream ofs_odd(argv[2]), ofs_even(argv[3]);std::istream_iterator<int> in(ifs), in_eof;std::ostream_iterator<int> out_odd(ofs_odd, " "), out_even(ofs_even, "\n");std::for_each(in, in_eof, [&out_odd, &out_even](const int i){*(i & 0x1 ? out_odd : out_even)++ = i;});return 0;
}

练习10.34

使用 reverse_iterator 逆序打印一个vector

解:

#include <bits/stdc++.h>using namespace std;int main()
{ifstream inpt;inpt.open("mnt.txt", ios::in);if (!inpt.is_open()){cout << "文件打开失败" << endl;return -1;}vector<int> vi;int val;while (inpt >> val)vi.push_back(val);for (auto r_itre = vi.crbegin(); r_itre != vi.crend(); ++ r_itre)cout << *r_itre << " ";cout << endl;return 0;
}

练习10.35

使用普通迭代器逆序打印一个vector

解:

#include <bits/stdc++.h>using namespace std;int main()
{ifstream inpt;inpt.open("mnt.txt", ios::in);if (!inpt.is_open()){cout << "文件打开失败" << endl;return -1;}vector<int> vi;int val;while (inpt >> val)vi.push_back(val);for (auto r_iter = vi.cend(); r_iter != vi.begin(); )cout <<*(-- r_iter) << " ";cout << endl;return 0;
}

练习10.36

使用 find 在一个 intlist 中查找最后一个值为0的元素。

解:

#include <bits/stdc++.h>using namespace std;int main()
{list<int> li = {0, 1, 2, 3, 4, 5, 0, 6};auto last_z = find(li.rbegin(), li.rend(), 0);last_z ++ ; int p = 0;for (auto iter = li.begin(); iter != last_z.base(); iter ++ , p ++ );if (p >= li.size())cout << "此容器中没有0" << endl;else cout << "最后一个0在"  << p << endl;cout << endl;return 0;
}

练习10.37

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

解:

#include <iostream>
#include <list>
#include <algorithm>
#include <vector>
#include <iterator>using namespace std;int main()
{vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };list<int> l;copy(v.crbegin() + 3, v.crbegin() + 8, back_inserter(l));for (auto i : l) std::cout << i << " ";cout << endl;return 0;
}

练习10.38

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

  • 输入迭代器 : ==,!=,++,*,->
  • 输出迭代器 : ++,*
  • 前向迭代器 : ==,!=,++,*,->
  • 双向迭代器 : ==,!=,++,--,*,->
  • 随机访问迭代器 : ==,!=,<,<=,>,>=,++,--,+,+=,-,-=,*,->,iter[n]==*(iter+n)

练习10.39

list 上的迭代器属于哪类?vector呢?

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

练习10.40

你认为 copy 要求哪类迭代器?reverseunique 呢?

  • copy 需要两个输入迭代器,一个输出迭代器
  • reverse 需要双向迭代器
  • unique需要随机访问迭代器

练习10.41

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

replace(beg, end, old_val, new_val);
replace_if(beg, end, pred, new_val);
replace_copy(beg, end, dest, old_val, new_val);
replace_copy_if(beg, end, dest, pred, new_val);

解:

  • replace 在迭代器范围内用新值替换所有原来的旧值。
  • replace_if 在迭代器范围内,满足谓词条件的元素用新值替换。
  • replace_copy 复制迭代器范围内的元素到目标迭代器位置,如果元素等于某个旧值,则用新值替换
  • replace_copy_if 复制迭代器范围内的元素到目标迭代器位置,满足谓词条件的元素用新值替换

练习10.42

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

解:

#include <iostream>
#include <string>
#include <list>using std::string; using std::list;void elimDups(list<string> &words)
{words.sort();words.unique();
}int main()
{list<string> l = { "aa", "aa", "aa", "aa", "aasss", "aa" };elimDups(l);for (const auto& e : l)std::cout << e << " ";std::cout << std::endl;
}

【c++primer第五版】第十章习题答案相关推荐

  1. 数据库(第五版)课后习题答案

    仅供参考,有任何问题概不负责,请同学们谨慎参考!!! 数据库系统概论第五版 答案 第1章 绪论 1 .试述数据.数据库.数据库系统.数据库管理系统的概念. 答:( l )数据( Data ) :描述事 ...

  2. C++ Primer 第五版 部分课后题答案

    当时刚学C++的时候买了这本书,一开始前面看的一知半解,索性就先缓缓,等学完学校的C++课程(中途自己也写了不少c++的代码),一段时间之后又拿起这本书去看,感觉还是挺有滋味的,这本书对我印象中的C+ ...

  3. 数字逻辑与数字系统(第五版)课后习题答案

    (519条消息) 数字逻辑与数字电路指导(课后题)_Half-up的博客-CSDN博客 转载,仅供学习方便查阅

  4. C++ Primer 第五版 课后章节练习答案 第一、二章

    编译软件为 vs2015. 第一章 练习1.9: 编写程序,使用 while 循环将 50 到100 的整数相加. #include "stdafx.h" #include< ...

  5. C++Primer第五版——习题答案+详解(完整版)

     C++Primer第五版--习题答案详解 新手入门必看的书.知识是一个系统化并且相互关联的体系,零散的东西每天收获如果不形成自己的体系的话,那将是毫无意义的,所以我觉得有必要将这本书先啃一遍,消化其 ...

  6. C++Primer第五版——习题答案详解

     C++Primer第五版--习题答案详解 新手入门必看的书.知识是一个系统化并且相互关联的体系,零散的东西每天收获如果不形成自己的体系的话,那将是毫无意义的,所以我觉得有必要将这本书先啃一遍,消化其 ...

  7. C++ primer 第五版习题答案, Stanley B. Lippman( 斯坦利 李普曼)(持续更新中)

    最新重新看c++ primer 5 第五版本,看到网上很多人在找答案,而这本书是2013年9月份的样子出来的,网上肯定是没有标准答案的,而很多人冒天下之大不韪用c plus plus的答案来来骗取分数 ...

  8. C++Primer第五版 习题答案 目录

    C++Primer第五版 习题答案 本文当作我学习C++的一个记录,这里的习题答案并不是标准答案,仅仅是我的理解,如有错误,请大家指出,谢谢! 参考的文章会在文末列出. 使用的系统为:ubuntu 1 ...

  9. C++ Primer 第五版 第7章类 7.1——类讲解(成员函数、非成员函数、构造函数)习题答案

    理论讲解请参考:C++ Primer 第五版 第7章类 7.1--类讲解(成员函数.非成员函数.构造函数) 目录 7.1 定义抽象数据类型习题答案 7.4&7.5 7.6&7.7 7. ...

  10. C++ Primer 第五版 第6章——函数阅读笔记及习题答案(完整,附C++代码)

    C++Primer(第五版)第6章函数的阅读笔记及课后习题答案总结,课后习题答案是自己学习写出来的,如果有误,欢迎指正 还不完整,后续会更新添加 阅读笔记 C++ Primer 第五版 第6章 6.1 ...

最新文章

  1. 浅谈ATP CHECK zz
  2. Slickflow.NET 开源工作流引擎基础介绍-.NET Core2.0 版本实现介绍
  3. python 中移去文件的只读属性
  4. 获取当前系统时间c语言,使用C语言获取当前系统的时间
  5. ip地址配置 mongodb_MongoDB安全配置详解
  6. PreparedStatement.SetDate
  7. [转载] Ajax中使用Response.Write输出javascript脚本出错的解决办法
  8. QT调用OpenCV
  9. Unity 下载 国际版 去壳版,有网就行,下载不下来你打我。
  10. 圆和长方形周长相等谁的面积大_周长相等,正方形、长方形、圆形谁的面积最大?...
  11. 骇客学堂:网络入侵检测初步探测方法
  12. 关键对话(如何高效沟通)读书总结
  13. c语言10个选手10个评委,C语言歌星大奖赛为参赛的选手打分.doc
  14. Laya Stage
  15. Android中修改ScrollBar默认样式
  16. 阿里云OSS图床搭建方法
  17. jackson多态序列化与反序列化
  18. git创建分支并推到远端
  19. 前端知识点总结——H5
  20. AI自动识别户型图生成3D场景方案

热门文章

  1. Ant Design Vue 相关介绍
  2. Pytorch的优化器总结归纳
  3. AutoLeaders控制组—51单片机学习笔记
  4. 剖析visa信用卡支付的交易处理流程
  5. 【安装系统】U盘安装系统教程,使用UltraISO制作U盘启动盘
  6. Halo 开源项目学习(一):项目启动
  7. 【新手教程】51Sim-One Cloud 2.0如何构建一个V2X案例
  8. 漂亮大气的html导航页面,非常大气漂亮的CSS导航栏
  9. 短视频矩阵系统,抖音矩阵系统源码,抖音SEO源码。
  10. “凡客好声音”摇滚派对专场 正火热抢票中!