编译软件为 vs2015。
第十章
练习10.1:
头文件 algorithm 中定义了一个名为 count 的函数,它类似 find,接受一对迭代器和一个值作为参数。count 返回给定值在序列中出现的次数。编写程序,读取 int 序列存入 vector 中,打印有多少个元素的值等于给定值。
解答:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec;
int num;
int find_num;
cout << "please input numbers and the last will be the number you want to look for: " << endl;
while (cin >> num)
{
vec.push_back(num);
}
cin >> num;
auto result = count(vec.cbegin(), vec.cend(), num);
cout << num << " appeared " << result << " times" << endl;
system("pause");
return 0;
}
练习10.2:
重做上一题,但读取 string 序列存入 list 中。
解答:
#include <algorithm>
#include <iostream>
#include <list>
#include <string>
using namespace std;
int main()
{
list<string> lis;
cout << "please input your words:" << endl;
string str;
string s = "to";
while (cin >> str)
{
lis.push_back(str);
}
auto result = count(lis.cbegin(), lis.cend(), s);
cout << s << " appeared " << result << " times " << endl;
system("pause");
return 0;
}
练习10.3:
用 accumulate 求一个 vector<int> 中的元素之和。
解答:
#include <numeric>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec;
cout << "please input: " << endl;
int num;
while (cin >> num)
{
vec.push_back(num);
}
auto result = accumulate(vec.cbegin(), vec.cend(), 0);
cout << "answer: " << result << endl;
system("pause");
return 0;
}
练习10.4:
假定 v 是一个 vector<double>,那么调用 accumulate(v.cbegin(), v.cend(), 0) 有何错误(如果存在的话)?
解答:
accumulate 函数假定的是要相加的序列的元素必须与第三个参数的类型匹配,或者能转换为第三个参数的类型,所以上述程序的输出结果是错误的,在执行假发操作时会省略掉加数后面的所有小数。
练习10.5:
在本节对名册 (roster) 调用 equal 的例子中,如果两个名册中保存的都是 c 风格字符串而不是 string,会发生什么?
解答:
c 风格字符串使用迭代器比较的是他们的地址,而不是字符串本身。
练习10.6:
编写程序,使用 fill_n 将一个序列中的 int 值都设置为 0 。
解答:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec = { 1,2,3,4,5 };
int num;
cout << "please input: " << endl;
while (cin >> num)
{
vec.push_back(num);
}
cout << "===================================" << endl;
for (auto &c : vec)
cout << c << " ";
cout << endl;
fill_n(vec.begin(), vec.size(), 0);
cout << "===================================" << endl;
for (auto &c : vec)
cout << c << " ";
system("pause");
return 0;
}
注意:不要在空的 vector 中使用函数 fill_n 操作。
练习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)要执行 copy 操作首先要确保拷贝到的对象长度与被拷贝对象的容器长度至少一样长,上述程序中没有指定 vec 的长度因此是错的,在拷贝函数前添加代码 vec.resize(lst.size);
(b) reserve(10) 的作用是分配至少能容纳是个元素的内存空间,但是其并不改变容器的元素数量,因此 vec 依旧为空,需要在fill_n 函数操作前添加代码 vec.resize(10);
练习10.8:
本节提到过,标准库算法不会改变它们所操作的容器的大小。为什么使用 back_insert 不会是使这一断言失效?
解答:
因为back_inserter是一种向容器中添加元素的迭代器。标准库算法不会改变它们所操作的容器的大小,但是迭代器可以通过使用容器操作来改变大小。
练习10.9:
实现你自己的 elimDups。测试你的程序,分别在读取输入后,调用 unique 后以及调用 erase 后打印 vector 的内容。
解答:
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void elimDups(vector<string> &words)
{
sort(words.begin(), words.end());
auto eu = unique(words.begin(), words.end());
words.erase(eu, words.end());
}
int main()
{
vector<string> story;
string str;
cout << "please input your words: " << endl;
while (cin >> str)
{
story.push_back(str);
}
cout << "==============================" << endl;
for (auto &c : story)
cout << c << " ";
cout << endl;
elimDups(story);
cout << "==============================" << endl;
for (auto &c : story)
cout << c << " ";
cout << endl;
system("pause");
return 0;
}
练习10.10:
你认为算法不改变容器大小的原因是什么?
解答:
因为算法是在迭代器上操作的,而不是容器上,所以算法不能直接添加和删除元素。
练习10.11:
编写程序,使用 stable_sort 和 isShorter 将传递给你的 elimDups 版本的 vector 排序。打印 vector 的内容, 验证你的程序的正确性。
解答:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
void elimDups(vector<string> &words)
{
sort(words.begin(), words.end());
auto eu = unique(words.begin(), words.end());
words.erase(eu, words.end());
}
bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}
int main()
{
vector<string> vec;
string str;
while (cin >> str)
{
vec.push_back(str);
}
elimDups(vec);
stable_sort(vec.begin(), vec.end(), isShorter);
cout << "===========================================" << endl;
for (const auto &s : vec)
cout << s << " ";
cout << endl;
system("pause");
return 0;
}
练习10.12:
编写名为 compareIsbn 的函数,比较两个 Sales_data 对象的 isbn() 成员。使用这个函数排序一个保存 Sales_data 对象的 vector。
解答:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Sales_Data
{
public:
string isbn;
Sales_Data() = default;
Sales_Data(const string &str) { isbn = str; };
};
bool compareIsbn(const Sales_Data &SD1, const Sales_Data &SD2)
{
return SD1.isbn < SD2.isbn;
}
int main()
{
Sales_Data sd1("Abcc1"), sd2("Mdgf"), sd3("Baxjfuh"), sd4("Ytgf7"), sd5("Emkme9");
vector<Sales_Data> vec{ sd1, sd2, sd3, sd4, sd5 };
cout << "===============================" << endl;
for (auto &v : vec)
{
for (auto &s : v.isbn)
cout << s;
cout << " ";
}
cout << endl;
sort(vec.begin(), vec.end(), compareIsbn);
cout << "===============================" << endl;
for (auto &c : vec)
{
for (auto &s : c.isbn)
cout << s;
cout << " ";
}
cout << endl;
system("pause");
return 0;
}
练习10.13:
标准库定义了名为 partition 的算法, 它接受一个谓词,对容器内容进行划分,使得谓词为 true 的值会排在容器的前半部分,而使谓词为 false 的值会排在后半部分。算法返回一个迭代器,指向最后一个使谓词为 true 的元素之后的位置。编写函数,接受一个 string, 返回一个 bool 值,指出 string 是否有 5 个或更多字符。使用此函数划分 words。打印出长度大于等于 5 的元素。
解答:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
bool isShorter(const string &words)
{
return 5 <= words.size();
}
int main()
{
string str;
vector<string> vec;
while (cin >> str)
{
vec.push_back(str);
}
auto resault = partition(vec.begin(), vec.end(), isShorter);
for (auto beg = vec.cbegin(); beg != resault; ++beg)
cout << *beg << " ";
cout << endl;
system("pause");
return 0;
}
练习 10.14:
编写一个 lambda, 接受两个 int, 返回它们的和。
解答:
auto lam = [ ](const int &a, const int &b ) { return a+b; }
练习10.15:
编写一个 lambda, 捕获它所在函数的 int,并接受一个 int 参数。lambda 应该返回捕获的 int 和 int 参数的和。
解答:
int i = 42;
auto lam = [ i ](int num) { return i+num; }
练习10.16:
使用 lambda 编写你自己版本的 biggies。
解答:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
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());
}
string make_plural(size_t ctr, const string &word, const string &ending)
{
return (ctr > 1 ? word + ending : word);
}
void biggies(vector<string> &words, vector<string>::size_type sz)
{
//将 words 按字典顺序排序,删除重复单词
elimDups(words);
//按长度排序,长度相同的单词维持字典顺序
stable_sort(words.begin(), words.end(),
[](const string &a, const string &b) {return a.size() < b.size(); });
// 获取一个迭代器,指向第一个满足 size()>= sz 的元素
auto wc = find_if(words.begin(), words.end(), [sz](const string &a) {return a.size() > sz; });
// 返回满足要求的单词数量
auto count = words.end() - wc;
cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer: " << endl;
for_each(wc, words.end(), [](const string &s) {cout << s << " "; });
cout << endl;
}
int main()
{
vector<string> vec;
string str;
while (cin >> str)
{
vec.push_back(str);
}
biggies(vec, 3);
system("pause");
return 0;
}
练习10.17:
重写 10.3.1 节练习(第 345 页)的程序,在对 sort 的调用中使用 lambda 来代替函数 compareIsbn
解答:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Sales_Data
{
public:
string isbn;
Sales_Data() = default;
Sales_Data(const string &str) { isbn = str; };
};
bool compareIsbn(const Sales_Data &SD1, const Sales_Data &SD2)
{
return SD1.isbn < SD2.isbn;
}
int main()
{
Sales_Data sd1("Abcc1"), sd2("Mdgf"), sd3("Baxjfuh"), sd4("Ytgf7"), sd5("Emkme9");
vector<Sales_Data> vec{ sd1, sd2, sd3, sd4, sd5 };
cout << "===============================" << endl;
for (auto &v : vec)
{
for (auto &s : v.isbn)
cout << s;
cout << " ";
}
cout << endl;
sort(vec.begin(), vec.end(), [](Sales_Data &s1, Sales_Data &s2) {return s1.isbn < s2.isbn; });
cout << "===============================" << endl;
for (auto &c : vec)
{
for (auto &s : c.isbn)
cout << s;
cout << " ";
}
cout << endl;
system("pause");
return 0;
}
练习10.18:
重写 biggies,用 partition 代替 find_if。我们在 10.3.1 节练习10.13 (第 345 页)中介绍了 partition 算法。
解答:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
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());
}
string make_plural(size_t ctr, const string &word, const string &ending)
{
return (ctr > 1 ? word + ending : word);
}
void biggies(vector<string> &words, vector<string>::size_type sz)
{
//将 words 按字典顺序排序,删除重复单词
elimDups(words);
//按长度排序,长度相同的单词维持字典顺序
stable_sort(words.begin(), words.end(),
[](const string &a, const string &b) {return a.size() < b.size(); });
// 获取一个迭代器,指向第一个满足 size()>= sz 的元素
//auto wc = find_if(words.begin(), words.end(), [sz](const string &a) {return a.size() > sz; });
auto wc = partition(words.begin(), words.end(), [sz](const string &a) {return a.size() < sz; });
// 返回满足要求的单词数量
auto count = words.end() - wc;
cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer: " << endl;
for_each(wc, words.end(), [](const string &s) {cout << s << " "; });
cout << endl;
}
int main()
{
vector<string> vec;
string str;
while (cin >> str)
{
vec.push_back(str);
}
biggies(vec, 5);
system("pause");
return 0;
}
练习10.19:
用 stable_partition 重写前一题的程序,与 stable_sort 类似,在划分后的序列中维持原有元素的顺序。
解答:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
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());
}
string make_plural(size_t ctr, const string &word, const string &ending)
{
return (ctr > 1 ? word + ending : word);
}
void biggies(vector<string> &words, vector<string>::size_type sz)
{
//将 words 按字典顺序排序,删除重复单词
elimDups(words);
//按长度排序,长度相同的单词维持字典顺序
stable_sort(words.begin(), words.end(),
[](const string &a, const string &b) {return a.size() < b.size(); });
// 获取一个迭代器,指向第一个满足 size()>= sz 的元素
//auto wc = find_if(words.begin(), words.end(), [sz](const string &a) {return a.size() > sz; });
auto wc = stable_partition(words.begin(), words.end(), [sz](const string &a) {return a.size() < sz; });
// 返回满足要求的单词数量
auto count = words.end() - wc;
cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer: " << endl;
for_each(wc, words.end(), [](const string &s) {cout << s << " "; });
cout << endl;
}
int main()
{
vector<string> vec;
string str;
while (cin >> str)
{
vec.push_back(str);
}
biggies(vec, 5);
system("pause");
return 0;
}
练习10.20:
标准库定义了一个名为 count_if 的算法。类似 find_if,此函数接受一对迭代器,表示一个输入范围,还接受一个谓词,会对输入范围中每个元素执行。count_if 返回一个计数值,表示谓词还有多少次为真。使用 count_if 重写我们程序中统计有多少单词长过 6 的部分。
解答:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
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());
}
string make_plural(size_t ctr, const string &word, const string &ending)
{
return (ctr > 1 ? word + ending : word);
}
void biggies(vector<string> &words, vector<string>::size_type sz)
{
//将 words 按字典顺序排序,删除重复单词
elimDups(words);
//按长度排序,长度相同的单词维持字典顺序
stable_sort(words.begin(), words.end(),
[](const string &a, const string &b) {return a.size() < b.size(); });
// 获取一个迭代器,指向第一个满足 size()>= sz 的元素
//auto wc = find_if(words.begin(), words.end(), [sz](const string &a) {return a.size() > sz; });
auto wc = count_if(words.begin(), words.end(), [sz](const string &a) {return a.size() > sz; });
cout << wc << " words " << " of length " << sz << " or longer " << endl;
//输出长度满足要求的元素
for (size_t i = words.size() - wc; i != words.size(); ++i)
cout << words[i] << " ";
cout << endl;
}
int main()
{
vector<string> vec;
string str;
while (cin >> str)
{
vec.push_back(str);
}
biggies(vec, 6);
system("pause");
return 0;
}
练习10.21:
编写一个 lambda,捕获一个局部 int 变量,并递减变量值,直至它变为 0。一旦变量变为 0,在调用 lambda 应该不再递减变量。 lambda 应该返回一个 bool 值,指出捕获的变量是否为 0。
解答:
#include <iostream>
using namespace std;
int main()
{
int v = 13;
auto f = [&v]()
{
if (v == 0)
return true;
else
{
--v;
return false;
}
};
while (!f())
cout << v << " ";
cout << endl;
system("pause");
return 0;
}
练习10.22:
重写统计长度小于等于 6 的单词数量的程序,使用函数代替 lambda。
解答:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
using namespace std::placeholders;
bool isShorter(const string &a, const string &b)
{
return a.size() < b.size();
}
bool isShorterof6(const string &a)
{
return a.size() <= 6;
}
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());
}
string make_plural(size_t ctr, const string &word, const string &ending)
{
return (ctr > 1 ? word + ending : word);
}
void biggies(vector<string> &words, vector<string>::size_type sz)
{
//将 words 按字典顺序排序,删除重复单词
elimDups(words);
//按长度排序,长度相同的单词维持字典顺序
stable_sort(words.begin(), words.end(), bind(isShorter, _1, _2));
// 获取一个迭代器,指向第一个满足 size()>= sz 的元素
auto wc = count_if(words.begin(), words.end(), bind(isShorterof6, _1));
cout << wc << " words " << " of length " << sz << " or shorter " << endl;
//输出长度满足要求的元素
for (size_t i = 0; i != wc; ++i)
cout << words[i] << " ";
cout << endl;
}
int main()
{
vector<string> vec;
string str;
while (cin >> str)
{
vec.push_back(str);
}
biggies(vec, 6);
system("pause");
return 0;
}
练习10.23:
bind 接受几个参数?
解答:
若要绑定的函数有 n 个参数,则 bind 有 n+1 个参数,其中一个是绑定的函数本身。
练习10.24:
给定一个 string,使用 bind 和 check_size 在一个 int 的 vector 中查找第一个大于 string 长度的值。
解答:
#include <iostream>
#include <vector>
#include <string>
#include <functional>
#include <algorithm>
using namespace std;
using namespace std::placeholders;
bool check_size(const string &s, const size_t sz)
{
return s.size() < sz;
}
int main()
{
vector<int> vec;
int num;
string str;
cout << "please input the word: " << endl;
cin >> str;
cout << "please input the numbers: " << endl;
while (cin >> num)
vec.push_back(num);
auto result = find_if(vec.begin(), vec.end(), bind(check_size, str, _1));
cout << str << " of length: " << str.size() << endl;
cout << "====================================" << endl;
cout << "the first longer than " << str << " is: " << *result << endl;
system("pause");
return 0;
}
练习10.25:
在 10.3.2 节(第 349 页)的练习中,编写了一个使用 partiition 的 biggies 版本。使用 check_size 和 bind 重写此函数。
解答:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std::placeholders;
using namespace std;
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());
}
string make_plural(size_t ctr, const string &word, const string &ending)
{
return (ctr > 1 ? word + ending : word);
}
bool check_size(const string &s, const size_t sz)
{
return s.size() >= sz;
}
void biggies(vector<string> &words, vector<string>::size_type sz)
{
//将 words 按字典顺序排序,删除重复单词
elimDups(words);
//按长度排序,长度相同的单词维持字典顺序
stable_sort(words.begin(), words.end(),
[](const string &a, const string &b) {return a.size() < b.size(); });
// 获取一个迭代器,指向第一个满足 size()>= sz 的元素
auto wc = partition(words.begin(), words.end(), bind(check_size, _1, sz));
// 返回满足要求的单词数量
auto count = wc - words.begin();
cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer: " << endl;
for_each(words.begin(), wc, [](const string &s) {cout << s << " "; });
cout << endl;
}
int main()
{
vector<string> vec;
string str;
while (cin >> str)
{
vec.push_back(str);
}
biggies(vec, 5);
system("pause");
return 0;
}
练习10.26:
解释三种插入迭代器的不同之处。
解答:
back_inserter 创建一个使用push_back的迭代器。
front_inserter 创建一个使用push_front的迭代器,元素总是插入到容器的。
inserter 创建一个使用 insert 的迭代器。此函数接受第二个参数,这个参数必须是一个指向给定容器的迭代器。元素被插入到给定迭代器所表示的元素之前。
练习10.27:
除了 unique(参见 10.2.3 节,第 343 页)之外,标准库还定义了名为 unique_copy 的函数, 它接受第三个迭代器,表示宝贝不重复元素的目的位置。编写一个程序,使用 unique_copy 将一个 vector 中不重复的元素拷贝到一个初始为空的 list 中。
解答:
#include <iostream>
#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
using namespace std;
int main()
{
cout << "please input: " << endl;
int num;
vector<int> vec;
while (cin >> num)
{
vec.push_back(num);
}
sort(vec.begin(), vec.end());
list<int> list;
unique_copy(vec.cbegin(), vec.cend(), back_inserter(list));
for (const auto &c : list)
cout << c << " ";
cout << endl;
system("pause");
return 0;
}
练习10.28:
一个 vector 中保存 1 到 9,将其拷贝到三个其他容器中。分别使用 inserter、back_inserter 和 front_inserter 将元素添加到三个容器中。对每种 inserter,估计序列是怎样的,运行程序验证你的估计是否正确。
解答:
#include <vector>
#include <list>
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
vector<int> vec{ 1,2,3,4,5,6,7,8,9 };
vector<int> vec1;
list<int> list1, list2;
copy(vec.begin(), vec.end(), back_inserter(vec1));
for (const auto &v : vec1)
cout << v << " ";
cout << endl;
copy(vec.begin(), vec.end(), front_inserter(list1));
for (const auto &v : list1)
cout << v << " ";
cout << endl;
copy(vec.begin(), vec.end(), inserter(list2, list2.begin()));
for (const auto &v : list2)
cout << v << " ";
cout << endl;
system("pause");
return 0;
}
练习10.29:
编写程序,使用流迭代器读取一个文本文件,存入一个 vector 中国的 string 里。
解答:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
using namespace std;
int main()
{
ifstream in("...\\helloworld.txt");
istream_iterator<string> in_iter(in), eof;
vector<string> vec;
while(in_iter != eof)
{
vec.push_back(*in_iter++);
}
ostream_iterator<string> out_iter(cout, " ");
for (auto &c : vec)
*out_iter++ = c;
cout << endl;
return 0;
}
练习10.30:
使用流迭代器、sort 和 copy 从标准输入读取一个整数序列,将其排序,并将结果写到标准输出。
解答:
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> vec;
istream_iterator<int> in_iter(cin), eof;
ostream_iterator<int> out_iter(cout, " ");
while (in_iter != eof);
{
vec.push_back(*in_iter++);
}
sort(vec.begin(), vec.end());
copy(vec.begin(), vec.end(), out_iter);
cout << endl;
system("pause");
return 0;
}
练习10.31:
修改前一题的程序,使其只打印不重复的元素。你的程序应该使用 unique_copy (参见 10.4.1 节,第 359 页)。
解答:
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> vec;
istream_iterator<int> in_iter(cin), eof;
ostream_iterator<int> out_iter(cout, " ");
while (in_iter != eof)
{
vec.push_back(*in_iter++);
}
sort(vec.begin(), vec.end());
unique_copy(vec.begin(), vec.end(), out_iter);
cout << endl;
system("pause");
return 0;
}
练习10.32:
重写 1.6 节(第 21 页)中的书店程序,使用一个 vector 保存交易记录,使用不同算法完成处理。使用 sort 和 10.3.1 节(第 345 页)中的 compareIsbn 函数来排序交易记录,然后使用 find 和 acculumate 求和。
解答:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <numeric>
#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(),
[](Sales_item const& lhs, Sales_item const& rhs) {
return lhs.isbn() < rhs.isbn();
});
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;
}
system("pause");
return 0;
}
练习10.33:
编写程序,接受三个参数:一个输入文件和两个输出文件的文件名。输入文件保存的应该是整数。使用 istream_iterator 读取输入文件。使用 ostream_iterator 将奇数写入第一个输出文件,每个值后面都跟一个空格。将偶数写入第二个输出文件,每个值都独占一行。
解答:
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
using namespace std;
int main()
{
vector<int> vec;
ifstream in("...\\input.txt");
ofstream out1("...\\output1.txt"), out2("...\\output2.txt");
istream_iterator<int> in_iter(in), eof;
ostream_iterator<int> out_iter1(out1, " "), out_iter2(out2, "\n");
while (in_iter != eof)
{
vec.push_back(*in_iter++);
}
for (auto &c : vec)
{
if (c % 2 == 1)
*out_iter1++ = c;
else
*out_iter2++ = c;
}
system("pause");
return 0;
}
练习 10.34:
使用 reverse_iterator 逆序打印一个 vector。
解答:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> vec = { 0,1,2,3,4,5,6,7,8,9 };
for (auto comma = vec.crbegin(); comma != vec.crend(); ++comma)
cout << *comma << " ";
cout << endl;
return 0;
}
练习10.35:
使用普通迭代器逆序打印一个 vector。
解答:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> vec = { 0,1,2,3,4,5,6,7,8,9 };
for (auto comma = vec.cend(); comma != vec.cbegin();)
cout << *--comma << " ";
cout << endl;
system("pause");
return 0;
}
练习10.36:
使用 find 在一个 int 的 list 中查找最后一个值为 0 的元素。
解答:
#include<iostream>
#include<list>
#include<string>
using namespace std;
int main()
{
list<int> list = { 1,3,4,0,2,5,0,9,7,0,8,6,3 };
for (auto c = list.cbegin(); c != list.cend(); ++c)
cout << *c << " ";
cout << endl;
auto answer = find(list.crbegin(), list.crend(), 0);
cout << *answer << " ";
for (auto iter = answer.base(); iter != list.cend(); ++iter)
cout << *iter << " ";
cout << endl;
system("pause");
return 0;
}
练习10.37:
给定一个包含 10 个元素的 vector ,将位置 3 到 7 之间的元素按逆序拷贝到一个 list 中。
解答:
#include<iostream>
#include<list>
#include<vector>
using namespace std;
int main()
{
vector<int> vec = { 0,1,2,3,4,5,6,7,8,9 };
list<int> list;
for (auto iter = vec.crbegin() + 3; iter != vec.crend() - 2; ++iter)
list.push_back(*iter);
for (auto c = list.cbegin(); c != list.cend(); ++c)
cout << *c << " ";
cout << endl;
system("pause");
return 0;
}
练习10.38:
列出 5 个迭代器类别,以及每类迭代器所支持的操作。
解答:
1. 前向迭代器(forward iterator): 可以读写元素。==
, !=
, ++
, *
, ->
2. 双向迭代器(bidirectional iterator):可以正向/反向读写序列中的元素。==
, !=
, ++
, --
, *
, ->
3. 随机访问迭代器(random-access iterator): 提供在常量时间内访问序列中任意元素的能力。支持双向迭代器的所有操作,同时还支持 iter+n,iter-n,iter+=n,iter-=n,iter1-iter2,>,>=,<,<=。
4. 输入迭代器:可以读取序列中的元素。==,!=,++,*,->
5. 输出迭代器:只写而不读元素。++,*
练习10.39:
list 上的迭代器属于哪类?vector 呢?
解答:
list 上的是双向迭代器, vector 上的是随机访问迭代器。
练习10.40:
你认为 copy 要求哪类迭代器?reverse 和 unique 呢?
解答:
copy:前两个是输入迭代器,最后一个是输出迭代器。
reserve:双向迭代器。
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)
解答:
1. 在 beg 到 end 的序列中用 new_ val 替换 old_val。
2. 在 beg 到 end 序列间用 new_val 替换使 pred 为真的值。
3. 在 beg 到 end 的序列间用 new_val 替换 old_val 并输出到 dest。
4. 在 beg 到 end 的序列间用 new_val 替换使 pred 为真的值,并输出到 dest。
练习10.42:
使用 list 代替 vector 重新实现 10.2.3 节(第 343 页)中的去除重复单词的程序。
解答:
#include<iostream>
#include<list>
#include<string>
using namespace std;
void elimDups(list<string> &words)
{
words.sort(); //排序
words.unique(); // 删除重复元素
}
int main()
{
list<string> list = { "the", "quick", "red", "fox","jumps", "over", "the","slow", "turtle" };
for (auto &s : list)
cout << s << " ";
cout << endl;
elimDups(list);
for (const auto &c : list)
cout << c << " ";
cout << endl;
system("pause");
return 0;
}