练习 10.1 && 练习 10.2
#include
#include
#include
#include
using namespace std;
int main()
{
vector iv = { 3,2,3,4,3,5 };
cout << count(iv.begin(), iv.end(), 3) << endl;
list lst = { "hello", "C++", "hello", "Python" };
cout << count(lst.begin(), lst.end(), "hello") << endl;
return 0;
}
练习 10.3:
#include
using namespace std;
#include
#include
#include
int main()
{
vector v = { 1,2,3,4,5 };
int sum = accumulate(v.begin(), v.end(), 0);
cout << sum << endl;
return 0;
}
练习 10.4:
#include
using namespace std;
#include
#include
#include
// accumulate的第三个参数是和的初始值,它还决定了函数的返回类型,以及函数中使用哪个加法运算符。
// 第三个参数为0则使用整型加法运算符。正确的调用方法是将0.0作为第三个参数传递给accumulate.
int main()
{
vector v2 = { 1.1,2.2,3.3};
double sum1 = accumulate(v2.begin(), v2.end(), 0); // sum1 = 6
double sum2 = accumulate(v2.begin(), v2.end(), 0.0); // sum2 = 6.6
cout << sum1 << " " << sum2 << endl;
return 0;
}
练习 10.5:
#include
#include
#include
#include
using namespace std;
int main()
{
vector roster1{ "Hello Cpp" };
vector roster2{ "Hello Cpp" };
bool ret = equal(roster1.begin(), roster1.end(), roster2.begin()); // 正常调用
cout << ret << endl;
return 0;
}
练习 10.6:
#include
#include
#include
using namespace std;
int main()
{
vector iv = { 0,1,2,3,4,5,6,7,8,9 };
fill_n(iv.begin(), iv.size(), 0);
for (auto i : iv)
cout << i << " ";
cout << endl;
return 0;
}
练习 10.7:
#include
#include
#include
#include
using namespace std;
int main()
{
// a
vector vec; list lst; int i;
while (cin >> i)
lst.push_back(i);
// copy算法要求目标序列至少要包含与源序列一样多的元素
// copy(lst.cbegin(), lst.cend(), vec.begin());
copy(lst.cbegin(), lst.cend(), back_inserter(vec));
// b
vector v;
v.reserve(10); // reserve申请容量,v的size为空
//fill_n(v.begin(), 10, 0); // v仍然为空,fill_n算法不具备向容器添加元素的能力
fill_n(back_inserter(v), 10, 0);
for (auto c : v)
cout << c << " ";
cout << endl;
return 0;
}
练习 10.8:
back_inserter是一种向容器种添加元素的迭代器迭代器,当一个算法操作一个这样的迭代器时,迭代器可以完成向容器添加元素的效果,但是标准库算法本身不直接操作容器,它们只操作迭代器,从而间接访问容器。
练习 10.9:
#include
#include
#include
#include
using namespace std;
void elimDips(vector& words)
{
// 按字典排序words,以便查找重复单词
sort(words.begin(), words.end());
// unique重排输入范围,使得每个单词只出现一次
// 排列在范围的前部,返回指向不重复区域之后一个位置的迭代器
auto unique_end = unique(words.begin(), words.end());
// 删除重复单词
words.erase(unique_end, words.end());
}
int main()
{
vector words{ "the", "quick","red","fox","jumps",
"over","the","slow","red","turtle" };
elimDips(words);
for (const auto& word : words)
cout << word << " ";
cout << endl;
return 0;
}
练习 10.10:
标准库算法对迭代器而不是容器进行操作。因此,算法不改变容器大小。
练习 10.11:
#include
#include
#include
#include
using namespace std;
void elimDips(vector& words)
{
sort(words.begin(), words.end());
auto unique_end = unique(words.begin(), words.end());
words.erase(unique_end, words.end());
}
bool isShorter(const string& s1, const string& s2)
{
return s1.size() < s2.size();
}
int main()
{
vector words{ "the", "quick","red","fox","jumps",
"over","the","slow","red","turtle" };
elimDips(words);
stable_sort(words.begin(), words.end(), isShorter);
for (const auto& word : words)
cout << word << " "; // fox red the over slow jumps quick turtle
cout << endl;
return 0;
}
练习 10.12:
#include
#include
#include
#include
using namespace std;
// 声明read函数
struct Sales_data;
istream& read(istream& is, Sales_data& item);
class Sales_data
{
friend Sales_data add(const Sales_data& lhs, const Sales_data& rhs);
friend istream& read(istream& is, Sales_data& item);
friend ostream& print(ostream& os, const Sales_data& item);
public:
// 构造函数
Sales_data() = default;
Sales_data(const string& s) :bookNo(s) {}
Sales_data(const string& s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n* p) {}
Sales_data(istream& is)
{
read(is, *this);
}
// 成员函数
string isbn() const;
const Sales_data& combine(const Sales_data& rhs);
private:
inline double avg_price()const;
private:
// 成员属性
string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
inline double Sales_data::avg_price()const
{
return units_sold ? revenue / units_sold : 0;
}
string Sales_data::isbn()const
{
return this->bookNo;
}
const Sales_data& Sales_data::combine(const Sales_data& rhs)
{
this->units_sold += rhs.units_sold;
this->revenue += rhs.revenue;
return *this;
}
Sales_data add(const Sales_data& lhs, const Sales_data& rhs)
{
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
istream& read(istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = item.units_sold * price;
return is;
}
ostream& print(ostream& os, const Sales_data& item)
{
os << item.bookNo << " " << item.units_sold << " " << item.revenue;
return os;
}
bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs)
{
return lhs.isbn() < rhs.isbn();
}
int main()
{
Sales_data d1("0 - 201 - 70353 - X", 4, 25.0), d2("0 - 201 - 82470 - 1", 4, 30.0),
d3("0 - 399 - 82477 - 1", 2, 15.00), d4("0 - 201 - 88954 - 4", 5, 12.00);
vector vec{ d1, d2, d3, d4 };
sort(vec.begin(), vec.end(), compareIsbn);
for (const auto& elem : vec)
print(cout, elem) << endl;
return 0;
}
练习 10.13:
#include
#include
#include
#include
using namespace std;
bool LengthGreaterFive(const string& s)
{
return s.size() > 5;
}
int main()
{
vector words{ "Cpp", "Java", "Python", "Golang" };
auto part = partition(words.begin(), words.end(), LengthGreaterFive);
for (auto iter = words.cbegin(); iter != part; ++iter)
cout << *iter << " ";
cout << endl;
return 0;
}
练习 10.14:
#include
using namespace std;
int main()
{
auto sum = [](int a, int b) {return a + b; };
cout << sum(1,1) << endl;
return 0;
}
练习 10.15:
#include
using namespace std;
int main()
{
int a = 6;
auto sum = [a](int b) {return a + b; };
cout << sum(3) << endl;
return 0;
}
练习 10.16:
#include
#include
#include
#include
using namespace std;
void elimDips(vector& words)
{
sort(words.begin(), words.end());
auto unique_end = unique(words.begin(), words.end());
words.erase(unique_end, words.end());
}
void biggies(vector& words, vector::size_type sz)
{
elimDips(words); // 按字典排序,删除重复单词
// 按长度排序,长度相同的单词维持字典排序
stable_sort(words.begin(), words.end(), [](const string& lhs, const string& rhs)
{return lhs.size() < rhs.size(); });
// 获取一个迭代器指向第一个满足s.size() >= sz的元素
auto wc = find_if(words.begin(), words.end(), [sz](const string& s)
{return s.size() >= sz; });
// 输出满足s.size() >= sz的元素
for_each(wc, words.end(), [](const string& s) {cout << s << " "; });
cout << endl;
}
int main()
{
vector words{ "the", "quick","red","fox","jumps",
"over","the","slow","red","turtle" };
biggies(words, 5);
return 0;
}
练习 10.17:
#include
#include
#include"Sales_data.h"
int main()
{
Sales_data d1("0 - 201 - 70353 - X", 4, 25.0), d2("0 - 201 - 82470 - 1", 4, 30.0),
d3("0 - 399 - 82477 - 1", 2, 15.00), d4("0 - 201 - 88954 - 4", 5, 12.00);
vector vec{ d1, d2, d3, d4 };
sort(vec.begin(), vec.end(), [](const Sales_data& sd1, const Sales_data& sd2)
{return sd1.isbn() < sd2.isbn();});
for (const auto& elem : vec)
print(cout, elem) << endl;
return 0;
}
练习 10.18 && 练习 10.19:
#include
#include
#include
#include
using namespace std;
void elimDips(vector& words)
{
sort(words.begin(), words.end());
auto unique_end = unique(words.begin(), words.end());
words.erase(unique_end, words.end());
}
// 10.18
void biggies_partition(vector& words, vector::size_type sz)
{
elimDips(words); // 按字典排序,删除重复单词
// 按长度排序,长度相同的单词维持字典排序
stable_sort(words.begin(), words.end(), [](const string& lhs, const string& rhs)
{return lhs.size() < rhs.size(); });
// 获取一个迭代器指向满足s.size() >= sz的元素之后的位置
auto partition_end = partition(words.begin(), words.end(), [sz](const string& s)
{return s.size() >= sz; });
// 输出满足s.size() >= sz的元素
for_each(words.begin(), partition_end, [](const string& s) {cout << s << " "; });
cout << endl;
}
// 10.19
void biggies_stable_partition(vector& words, vector::size_type sz)
{
elimDips(words); // 按字典排序,删除重复单词
// 按长度排序,长度相同的单词维持字典排序
stable_sort(words.begin(), words.end(), [](const string& lhs, const string& rhs)
{return lhs.size() < rhs.size(); });
// 获取一个迭代器指向满足s.size() >= sz的元素之后的位置
auto partition_end = stable_partition(words.begin(), words.end(), [sz](const string& s)
{return s.size() >= sz; });
// 输出满足s.size() >= sz的元素
for_each(words.begin(), partition_end, [](const string& s) {cout << s << " "; });
cout << endl;
}
int main()
{
vector words{ "the", "quick","red","fox","jumps",
"over","the","slow","red","turtle" };
biggies_partition(words, 5);
biggies_stable_partition(words, 5);
return 0;
}
练习 10.20:
#include
#include
#include
#include
using namespace std;
int main()
{
vector words{ "Cpppremer", "Java","Python","Golang" };
auto count = count_if(words.begin(), words.end(),
[](const string& s) {return s.size() > 6; });
cout << count << endl;
return 0;
}
练习 10.21:
#include
#include
#include
#include
using namespace std;
int main()
{
int i = 6;
auto f = [&i]()->bool
{
if (i)
{
--i;
return false;
}
else
return true;
};
while(!f())
cout << i << endl;
return 0;
}
练习 10.22:
#include
#include
#include
#include
#include
using namespace std;
using namespace placeholders;
bool lessThanOrEqualTo(const string& s, string::size_type sz)
{
return s.size() <= sz;
}
int main()
{
vector words{ "Cpppremer", "Java","Python","Golang" };
auto count = count_if(words.begin(), words.end(),
bind(lessThanOrEqualTo, _1, 6));
cout << count << endl;
return 0;
}
练习 10.23:
bind接受的参数为绑定的函数以及对应函数的参数;当使用bind生成一个可调用对象时,该对象的参数取决于bind中有几个占位符;
练习 10.24:
#include
#include
#include
#include
#include
using namespace std;
using namespace placeholders;
bool check_size(const string& s, string::size_type sz)
{
return s.size() < sz;
}
int main()
{
vector iv{ 0,1,2,3,4,5,6,7,8,9 };
string s("cpp");
auto ret = find_if(iv.begin(), iv.end(), bind(check_size, s, _1));
cout << *ret << endl;
return 0;
}
练习 10.25:
#include
#include
#include
#include
#include
using namespace std;
using namespace placeholders;
void elimDips(vector& words)
{
sort(words.begin(), words.end());
auto unique_end = unique(words.begin(), words.end());
words.erase(unique_end, words.end());
}
bool check_size(const string& s, string::size_type sz)
{
return s.size() >= sz;
}
void biggies_stable_partition(vector& words, vector::size_type sz)
{
elimDips(words);
stable_sort(words.begin(), words.end(), [](const string& lhs, const string& rhs)
{return lhs.size() < rhs.size(); });
auto partition_end = stable_partition(words.begin(), words.end(),
bind(check_size, _1, sz));
for_each(words.begin(), partition_end, [](const string& s) {cout << s << " "; });
cout << endl;
}
int main()
{
vector words{ "the", "quick","red","fox","jumps",
"over","the","slow","red","turtle" };
biggies_stable_partition(words, 5);
return 0;
}
练习 10.26:
back_inserter创建一个使用push_back的迭代器,front_inserter创建一个使用push_front的迭代器,inserter创建一个使用inserter的迭代器。back_inserter总是插入到容器尾元素之,front_inserter 总是插入到元素首元素之前,而inserter则是插入到给定位置之前。
练习 10.27:
#include
#include
#include
#include
#include
using namespace std;
int main()
{
vector iv{ 0,4,1,3,2,1,3,2 };
list lst;
sort(iv.begin(), iv.end());
unique_copy(iv.begin(), iv.end(), back_inserter(lst));
for (const auto& i : lst)
cout << i << " ";
cout << endl;
return 0;
}
练习 10.28:
#include
#include
#include
#include
#include
using namespace std;
void print(const list& lst)
{
for (const auto& i : lst)
cout << i << " ";
cout << endl;
}
int main()
{
vector iv{ 1,2,3,4,5,6,7,8,9 };
list l1;
copy(iv.begin(), iv.end(), inserter(l1, l1.begin()));
print(l1);
list l2;
copy(iv.begin(), iv.end(), back_inserter(l2));
print(l2);
list l3;
copy(iv.begin(), iv.end(), front_inserter(l3));
print(l3);
return 0;
}
练习 10.29:
#include
#include
#include
#include
using namespace std;
int main()
{
ifstream ifs("words.txt");
istream_iterator in(ifs), eof;
vector vec(in, eof);
// 输出
copy(vec.begin(), vec.end(), ostream_iterator(cout, "\n"));
return 0;
}
练习 10.30:
#include
#include
#include
#include
using namespace std;
int main()
{
istream_iterator in(cin), eof;
vector vec(in, eof);
sort(vec.begin(), vec.end());
copy(vec.begin(), vec.end(), ostream_iterator(cout, " "));
cout << endl;
return 0;
}
练习 10.31:
#include
#include
#include
#include
using namespace std;
int main()
{
istream_iterator in(cin), eof;
vector vec(in, eof);
sort(vec.begin(), vec.end());
unique_copy(vec.begin(), vec.end(), ostream_iterator(cout, " "));
cout << endl;
return 0;
}
练习 10.32:
#include
#include
#include
#include
#include"Sales_item.h"
using namespace std;
int main()
{
istream_iterator in(cin), eof;
vector vec(in, eof); // 保存交易记录
sort(vec.begin(), vec.end(), [](const Sales_item& lhs, const Sales_item& rhs)
{return lhs.isbn() < rhs.isbn(); });
for (auto beg = vec.begin(), end = beg; beg != vec.end(); beg = end)
{
end = find_if(beg, vec.end(), [beg](const Sales_item& item)
{return item.isbn() != beg->isbn(); });
auto total = accumulate(beg, end, Sales_item(beg->isbn()));
cout << total << endl;
}
return 0;
}
练习 10.33:
#include
#include
#include
#include
#include
using namespace std;
void fstream_in_out(ifstream& ifs, ofstream& ofs_odd, ofstream& ofs_even)
{
istream_iterator in(ifs), eof;
ostream_iterator out_odd(ofs_odd, " "), out_even(ofs_even, "\n");
while (in != eof)
*(*in % 2 ? out_odd : out_even)++ = *in++;
// 使用for_each
/*for_each(in, eof, [&out_odd, &out_even](const int i)
{*(i % 2 ? out_odd : out_even)++ = i; });*/
}
int main()
{
ifstream ifs("in.txt");
ofstream ofs_odd("odd.txt"), ofs_even("even.txt");
fstream_in_out(ifs, ofs_odd, ofs_even);
return 0;
}
练习 10.34:
#include
#include
#include
using namespace std;
int main()
{
vector vec{ 0,1,2,3,4,5,6,7,8,9 };
for_each(vec.crbegin(), vec.crend(), [](int i) {cout << i << " "; });
cout << endl;
return 0;
}
练习 10.35:
#include
#include
using namespace std;
int main()
{
vector vec{ 0,1,2,3,4,5,6,7,8,9 };
for (auto iter = vec.cend(); iter != vec.cbegin();)
cout << *(--iter) << " ";
cout << endl;
return 0;
}
练习 10.36:
#include
#include
#include
using namespace std;
int main()
{
list lst{ 6,0,2,3,0,5,0,7,8,9 };
auto zero_end = find(lst.crbegin(), lst.crend(), 0);
cout << "the last of " << *zero_end << " in front of " << *zero_end.base() << endl;
return 0;
}
练习 10.37:
#include
#include
#include
#include
using namespace std;
int main()
{
vector vec{ 0,1,2,3,4,5,6,7,8,9 };
list lst(7 - 3 + 1);
copy(vec.begin() + 3, vec.begin() + 8, lst.rbegin());
for_each(lst.begin(), lst.end(), [](int i) {cout << i << " "; });
cout << endl;
return 0;
}
练习 10.38:
练习 10.39:
list上的迭代器是双向迭代器,vector上的迭代器是随机访问迭代器。
练习 10.40:
练习 10.41:
// 将范围[beg, end)中的old_val替换为new_val
replace(beg, end, old_val, new_val);
// 将范围[beg, end)中谓词pred为真的元素替换为new_val
replace_if(beg, end, pred, new_val);
// 将范围[beg, end)中的old_val替换为new_val,并把元素拷贝到目的序列dest
replace_copy(beg, end, dest, old_val, new_val);
// 将范围[beg, end)中谓词pred为真的元素替换为new_val,并把元素拷贝到目的序列dest
replace_copy_if(beg, end, dest, pred, new_val);
练习 10.42:
#include
#include
#include
#include
using namespace std;
void elimDips(list& words)
{
words.sort();
words.unique();
}
int main()
{
list words{ "the", "quick","red","fox","jumps",
"over","the","slow","red","turtle" };
elimDips(words);
for_each(words.begin(), words.end(), [](const string& s) {cout << s << " "; });
cout << endl;
return 0;
}