声明:部分借鉴github项目:https://github.com/Mooophy/Cpp-Primer/tree/master/ch10
练习 10.12: 编写compareIsbn的函数,比较两个Sales_data对象的isbn()的成员
<span style="font-size:18px;">struct Sales_data{
string isbn;
Sales_data(string s){
isbn = s;
}
};
inline bool compareIsbn(const Sales_data& a, const Sales_data& b)
{
return a.isbn.size() < b.isbn.size();
}
int main()
{
Sales_data d1("aa"), d2("aaaa"), d3("aaa"), d4("z"), d5("aaaaz");
vector<Sales_data> v{ d1, d2, d3, d4, d5 };
sort(v.begin(), v.end(), compareIsbn);
for(const auto &elem : v)
cout << elem.isbn << " ";
cout << endl;
return 0;
}</span>
练习10.13 : 标准库定义了partition函数,用此函数划分words。打印长度大于等于5的元素
<span style="font-size:18px;">bool predicate(const string& s)
{
return s.size() >= 5;
}
int main()
{
auto v = vector<string>{ "a", "as", "aasss", "aaaaassaa", "aaaaaabba", "aaa" };
auto pivot = partition(v.begin(), v.end(), predicate);
for(auto it = v.cbegin(); it != pivot; ++ it)
cout << *it << endl;
return 0;
}</span>
练习 10.14: 编写一个lambda, 接受两个int, 返回它们的和
<span style="font-size:18px;"><span style="font-size:18px;">auto f = [](int a, int b){return a + b;};
cout << f(5, 6) << endl;</span></span>
练习 10.15: 编写一个lambda, 捕获它所在函数的int,并接受一个int参数,返回二者和。
<span style="font-size:18px;"><strong> </strong> int p = 10;
auto f = [p](int a){return p + a;};
cout << f(5) << endl;</span>
练习10.16: 使用lambda编写自己的版本biggies;
<span style="font-size:18px;">void elimDups(vector<string> &vec){
sort(vec.begin(), vec.end());
auto new_end = unique(vec.begin(), vec.end());
vec.erase(new_end, vec.end());
}
void biggies(vector<string> &vec, size_t sz)
{
elimDups(vec);
stable_sort(vec.begin(), vec.end(),
[](string const& lhs, string const& rhs){
return lhs.size() < rhs.size();
});
auto wc = find_if(vec.begin(), vec.end(),
[sz](string const& s) {
return s.size() >= sz;
});
for_each(wc, vec.end(), [](const string& s){
cout << s << " ";
});
cout << endl;
}
int main()
{
vector<string> v{"better", "hello", "world", "be", "better"};
biggies(v, 3);
return 0;
}</span>
练习10.17: 重写10.12的compareIsbn(), 利用lambda实现
<span style="font-size:18px;"><span style="font-size:18px;">struct Sales_data{
string isbn;
Sales_data(string s){
isbn = s;
}
};
int main()
{
Sales_data d1("aa"), d2("aaaa"), d3("aaa"), d4("z"), d5("aaaaz");
vector<Sales_data> v{ d1, d2, d3, d4, d5 };
sort(v.begin(), v.end(), [](const Sales_data& a, const Sales_data& b)
{return a.isbn.size() < b.isbn.size();});
for(const auto &elem : v)
cout << elem.isbn << " ";
cout << endl;
return 0;
}</span></span>
练习 10.18 10.19 重写biggies, partition和stable_partition实现
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">
void elimdups(vector<string> &vs)
{
sort(vs.begin(), vs.end());
auto new_end = unique(vs.begin(), vs.end());
vs.erase(new_end, vs.end());
}
// ex10.18
void biggies_partition(vector<string> &vs, size_t sz)
{
elimdups(vs);
auto pivot = partition(vs.begin(), vs.end(), [sz](const string &s){
return s.size() >= sz;}
);
for(auto it = vs.cbegin(); it != pivot; ++it)
cout << *it << " ";
}
// ex10.19
void biggies_stable_partition(vector<string> &vs, size_t sz)
{
elimdups(vs);
auto pivot = stable_partition(vs.begin(), vs.end(), [sz](const string& s){
return s.size() >= sz;
});
for(auto it = vs.cbegin(); it != pivot; ++it)
cout << *it << " ";
}
int main()
{
vector<string> v{
"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"
};
cout << "ex10.18: ";
vector<string> v1(v);
biggies_partition(v1, 4);
cout << endl;
// ex10.19
cout << "ex10.19: ";
vector<string> v2(v);
biggies_stable_partition(v2, 4);
cout << endl;
return 0;
}</span></span>
</span>
练习 10.20:标准库定义了一个count_if的算法。使用count_if重写程序中统计有多少个单词长度超过6.
<span style="font-size:18px;"><span style="font-size:18px;"> vector<string> vec{"hello", "world", "better", "is", "better", "less", "is", "more"};
int ans = count_if(vec.begin(), vec.end(), [](string s){ return s.size() >= 5; });
cout << ans << endl;</span></span>
练习 10.21: 编写一个lambda,捕获一个局部int变量,并递减变量值,直至它为0.一旦变量为0,再调用lambda不应该再递减变量。lambda应该返回一个bool值,指出捕获的变量是否为0.
<span style="font-size:18px;"> int index = 7;
auto check_and_decrement = [&index]() { return -- index ? false : true;};
while(!check_and_decrement())
cout << index << " ";
cout << index << endl;</span>
练习10.22: 重写统计长度小于等于5的单词数量的程序,使用函数代替lambda
<span style="font-size:18px;"><span style="font-size:18px;">bool isBiggerThan5(const string& s, string::size_type sz)
{
return s.size() > sz;
}
int main()
{
vector<string> vec{"hello", "world", "better", "is", "better", "less", "is", "more"};
cout << count_if(vec.begin(), vec.end(), bind(isBiggerThan5, _1, 5)) << endl;
return 0;
}</span></span>
练习10.24: 给定一个string, 使用bind和check_size在一个int的vector中查找第一个大于string长度的值。<span style="font-size:18px;">inline auto check_size(const string& s, string::size_type sz) -> bool
{
return s.size() >= sz;
}
inline auto find_first_greater(vector<int> const& v, string const& s) -> vector<int>::const_iterator
{
auto lambda = [&](int i) {return i >= 0 && bind(check_size, s, i)();};
return find_if(v.cbegin(), v.cend(), lambda);
}
int main()
{
vector<int> v{ -1, -2, 4, 3, 4, 5, 6, 7 };
string s("test");
cout << *find_first_greater(v, s) << endl;
}</span>
练习 10.25: 编写一个使用partition的biggies版本。使用check_size和bind重写此函数
<span style="font-size:18px;">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);
}</span>
练习 10.27: unique_copy, vector --> list
<span style="font-size:18px;"><strong> </strong><span style="font-size:18px;"> vector<int> v = {2, 3, 1, 1, 4};
list<int> lst;
unique_copy(v.begin(), v.end(), back_inserter(lst));
for_each(lst.begin(), lst.end(), [](const int val){ cout << val << " "; });
cout << endl;</span></span>
练习 10.29:编写程序,使用迭代器读取一个文本文件,存入一个vector的string中去。
<span style="font-size:18px;"> ifstream in("test.txt");
istream_iterator<string> in_it(in);
istream_iterator<string> in_eof;
vector<string> vec;
copy(in_it, in_eof, back_inserter(vec));
// output
copy(vec.begin(), vec.end(), ostream_iterator<string>(cout, " "));
</span>
<span style="font-size:18px;"> istream_iterator<int> in_it(cin), eof;
vector<int> vec(in_it, eof);
sort(vec.begin(), vec.end());
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
</span>
练习 10.31: 改写上题,采用unique_copy,输出不重复元素
<span style="font-size:18px;"> istream_iterator<int> in_it(cin), eof;
vector<int> vec(in_it, eof);
sort(vec.begin(), vec.end());
unique_copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));</span>
练习 10.33: 编写程序,输入3个参数,第一个为输入文件,其余二者为分别保存奇数和偶数的文件。
<span style="font-size:18px;"> ifstream in("test.txt");
ofstream even("even.txt");
ofstream odd("odd.txt");
istream_iterator<int> in_it(in), in_eof;
ostream_iterator<int> os1(even, "\n"), os2(odd, " ");
for_each(in_it, in_eof, [&os1, &os2](const int i) {
*(i & 0x1 ? os2 : os1) ++ = i;
});</span>
练习 10.34: 使用reverse_iterator逆序打印一个vector。
<span style="font-size:18px;"> istream_iterator<int> in_iter(cin), eof;
vector<int> vec(in_iter, eof);
for(vector<int>::reverse_iterator it = vec.rbegin(); it != vec.rend(); ++ it)
cout << *it << endl;</span>