10.1 && 10.2
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <list>
int main()
{
// 10.1
std::vector<int> v = {1, 2, 3, 4, 5, 6, 6, 6, 2};
std::cout << "ex 10.01: " << std::count(v.cbegin(), v.cend(), 6)
<< std::endl;
// 10.2
std::list<std::string> l = {"aa", "aaa", "aa", "cc"};
std::cout << "ex 10.02: " << std::count(l.cbegin(), l.cend(), "aa")
<< std::endl;
return 0;
}
10.3 && 10.4
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
int main()
{
// 10.3
std::vector<int> v = {1, 2, 3, 4};
std::cout << "ex 10.03: " << std::accumulate(v.cbegin(), v.cend(), 0)
<< std::endl;
// 10.4
std::vector<double> vd = {1.1, 0.5, 3.3};
std::cout << "ex 10.04: " << std::accumulate(vd.cbegin(), vd.cend(), 0)
<< std::endl;
return 0;
// 输出为4,而不是预期的4.9
}
10.5
在两个c样式字符串容器之间进行比较时,函数“equal”可能返回true。 尽管如此,我们需要记住,当涉及到c样式字符串的比较时,我们需要使用“strcmp”,而不仅仅是关系运算符,因为使用关系运算符只是两个c样式字符串地址之间的比较,而不是它们的值。
#include <algorithm>
#include <iostream>
#include <vector>
#include <list>
int main()
{
char c1[10] = "eipi10";
char c2[10] = "eipi10";
std::vector<char*> roster1{c1};
std::list<char*> roster2{c2};
std::cout << std::equal(roster1.cbegin(), roster1.cend(), roster2.cbegin());
return 0;
}
10.6
#include <iostream>
#include <vector>
#include <algorithm>
using std::vector;
using std::cout;
using std::endl;
using std::fill_n;
int main()
{
vector<int> vec{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
fill_n(vec.begin(), vec.size(), 0);
for (auto i : vec) cout << i << " ";
cout << endl;
}
10.7
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
using std::vector;
using std::cout;
using std::endl;
using std::list;
using std::cin;
using std::fill_n;
template <typename Sequence> void print(Sequence const& seq)
{
for (const auto& i : seq) cout << i << " ";
cout << endl;
}
int main()
{
vector<int> vec;
list<int> lst;
int i;
while (cin >> i) lst.push_back(i);
vec.resize(lst.size());
copy(lst.cbegin(), lst.cend(), vec.begin());
vector<int> v;
v.reserve(10);
fill_n(v.begin(), 10, 0);
print(v);
print(vec);
}
10.8
因为back_inserter是一个插入迭代器,即生成迭代器的迭代器适配器,该迭代器使用容器操作将元素添加到给定的容器中。算法不会改变大小,但迭代器可以通过使用容器操作来改变大小。
10.9
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
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
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <list>
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
#include <algorithm>
#include <numeric>
#include <vector>
#include "../ch07/ex7_26_sales_data.h" // Sales_data class.
bool compareIsbn(const Sales_data& sd1, const Sales_data& sd2)
{
return sd1.isbn() < sd2.isbn();
}
int main()
{
Sales_data d1("CppPrimer"), d2("JavaCore"), d3("PythonCookBook"),
d4("CppCore"), d5("AwesomeCPP");
std::vector<Sales_data> v{d1, d2, d3, d4, d5};
std::sort(v.begin(), v.end(), compareIsbn);
for (const auto& element : v) std::cout << element.isbn() << " ";
std::cout << std::endl;
}
10.13
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
bool predicate(const std::string& s)
{
return s.size() >= 5;
}
int main()
{
auto v = std::vector<std::string>{"a", "as", "aasss",
"aaaaassaa", "aaaaaabba", "aaa"};
auto pivot = std::partition(v.begin(), v.end(), predicate);
for (auto it = v.cbegin(); it != pivot; ++it) std::cout << *it << " ";
std::cout << std::endl;
return 0;
}
10.14
auto add = [](int lhs, int rhs){return lhs + rhs;};
10.15
int i = 42;
auto add = [i](int num){return i + num;};
10.16
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
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);
std::stable_sort(vs.begin(), vs.end(),
[](string const& lhs, string const& rhs) {
return lhs.size() < rhs.size();
});
auto wc = std::find_if(vs.begin(), vs.end(),
[sz](string const& s) { return s.size() >= sz; });
std::for_each(wc, vs.end(), [](const string& s) { std::cout << s << " "; });
}
int main()
{
std::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
#include <algorithm>
#include <vector>
#include "../ch07/ex7_26_sales_data.h" // Sales_data class.
int main()
{
Sales_data d1("CppPrimer"), d2("JavaCore"), d3("PythonCookBook"),
d4("CppCore"), d5("AwesomeCPP");
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() < sd2.isbn();
});
for (const auto& element : v) std::cout << element.isbn() << " ";
std::cout << std::endl;
}
10.18 && 10.19
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
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());
}
//10.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 << " ";
}
//10.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()
{
//10.18
std::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;
//10.19
std::cout << "ex10.19: ";
std::vector<std::string> v2(v);
biggies_stable_partition(v2, 4);
std::cout << std::endl;
return 0;
}
10.20
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using std::vector;
using std::string;
using std::cout;
using std::endl;
int main()
{
vector<string> words{"cppprimer", "pezy", "learncpp",
"greater", "rewrite", "programmer"};
cout << std::count_if(words.cbegin(), words.cend(), [](const string& word) {
return word.size() > 6;
}) << std::endl;
}
10.21
#include <iostream>
using std::cout;
using std::endl;
int main()
{
// local int variable
int local_val = 7;
auto decrement_to_zero = [&local_val]() {
if (local_val == 0)
return true;
else {
--local_val;
return false;
}
};
while (!decrement_to_zero()) cout << local_val << endl;
}
10.22
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using std::string;
using namespace std::placeholders;
bool lessThanOrEqualTo(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(lessThanOrEqualTo, _1, 6));
}
10.23
假设要绑定的函数有n个参数,则绑定取n+1个参数。另一个是函数自身绑定。
10.24
#include <iostream>
#include <string>
#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;
inline bool check_size(const string& s, string::size_type sz)
{
return s.size() < sz;
}
inline vector<int>::const_iterator find_first_bigger(const vector<int>& v,
const string& s)
{
return find_if(v.cbegin(), v.cend(),
bind(check_size, s, std::placeholders::_1));
}
int main()
{
vector<int> v{1, 2, 3, 4, 5, 6, 7};
string s("test");
cout << *find_first_bigger(v, s) << endl;
return 0;
}
10.25
#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。
insert使用insert>此函数接受第二个参数,该参数必须是给定容器的迭代器。元素插入在给定迭代器表示的元素之前。
10.27
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
int main()
{
std::vector<int> vec{3, 5, 1, 5, 1, 7, 3, 7, 9};
std::list<int> lst;
std::sort(vec.begin(), vec.end());
std::unique_copy(vec.begin(), vec.end(), back_inserter(lst));
for (auto i : lst) std::cout << i << " ";
std::cout << std::endl;
}
10.28
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
using std::list;
using std::copy;
using std::cout;
using std::endl;
template <typename Sequence> void print(Sequence const& seq)
{
for (const auto& i : seq) std::cout << i << " ";
std::cout << std::endl;
}
int main()
{
std::vector<int> vec{1, 2, 3, 4, 5, 6, 7, 8, 9};
// inserter
list<int> lst1;
copy(vec.cbegin(), vec.cend(), inserter(lst1, lst1.begin()));
print(lst1);
// back_inserter
list<int> lit2;
copy(vec.cbegin(), vec.cend(), back_inserter(lit2));
print(lit2);
// front_inserter
list<int> lst3;
copy(vec.cbegin(), vec.cend(), front_inserter(lst3));
print(lst3);
}
10.29
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <iterator>
using std::string;
int main()
{
std::ifstream ifs("../data/book.txt");
std::istream_iterator<string> in(ifs), eof;
std::vector<string> vec;
std::copy(in, eof, back_inserter(vec));
// output
std::copy(vec.cbegin(), vec.cend(),
std::ostream_iterator<string>(std::cout, "\n"));
}
10.30
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
std::istream_iterator<int> in_iter(std::cin), eof;
std::vector<int> vec;
while (in_iter != eof) vec.push_back(*in_iter++);
std::sort(vec.begin(), vec.end());
std::copy(vec.cbegin(), vec.cend(),
std::ostream_iterator<int>(std::cout, " "));
}
10.31
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
std::istream_iterator<int> in_iter(std::cin), eof;
std::vector<int> vec;
while (in_iter != eof) vec.push_back(*in_iter++);
std::sort(vec.begin(), vec.end());
std::unique_copy(vec.cbegin(), vec.cend(),
std::ostream_iterator<int>(std::cout, " "));
}
10.32
#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(),
[](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;
}
}
10.33
#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 - 10.37
#include <iostream>
#include <algorithm>
#include <list>
#include <vector>
int main()
{
std::vector<int> v = {4, 5, 7, 9, 6, 3, 1, 0, 2, 3};
//! 10.34
for (auto iter = v.crbegin(); iter != v.crend(); ++iter)
std::cout << *iter << " ";
std::cout << std::endl;
//! 10.35
for (auto iter = v.cend(); iter != v.cbegin();)
std::cout << *--iter << " ";
std::cout << std::endl;
//! 10.36
std::list<int> l = {3, 7, 0, 3, 4, 0, 5};
auto found = std::find(l.crbegin(), l.crend(), 0);
std::cout << *found << " in front of " << *found.base() << std::endl;
//! 10.37
std::list<int> ret_l(7 - 3 + 1);
std::reverse_copy(v.cbegin() + 3, v.cbegin() + 8, ret_l.begin());
for (auto i : ret_l)
std::cout << i << " ";
std::cout << std::endl;
}
10.38
输入迭代器:==,!=,++
输出迭代器:++
正向迭代器:==,!=,++,->
双向迭代器:==,!=,++,--,->
随机访问迭代器:==,!=,<,<=,>,>=,++,--,+,+=,-,
10.39
list具有双向迭代器。vector具有随机访问迭代器。
10.40
copy:第一个和第二个是输入迭代器,最后一个是输出迭代器。
reverse:双向迭代器。
unique:转发迭代器。
10.41
replace(beg, end, old_val, new_val); // replace the old_elements in the input range as new_elements.
replace_if(beg, end, pred, new_val); // replace the elements in the input range which pred is true as new_elements.
replace_copy(beg, end, dest, old_val, new_val); // copy the new_elements which is old_elements in the input range into dest.
replace_copy_if(beg, end, dest, pred, new_val); // copy the new_elements which pred is true in the input range into dest.
10.42
#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;
}