10.1
#include <iostream>
#include <algorithm> //count
#include <vector>
int main()
{
using namespace std;
vector<int> vec = { 4, 9, 3, 5, 8, 6, 6, 5, 4 };
cout << count(vec.begin(), vec.end(), 4); //统计4在vec元素里出现的次数
system("pause");
return 0;
}
10.2
#include <iostream>
#include <algorithm> //count
#include <list>
#include <string>
int main()
{
using namespace std;
list<string> lstr = { "c++", "main", "visual", "studio", "c++", "false", "true", "c++", "string", "c++" };
cout << "c++:" << count(lstr.begin(), lstr.end(), "c++"); //统计"c++"字符串在lstr中出现的次数
system("pause");
return 0;
}
10.3
#include <iostream>
#include <vector>
#include <numeric> //accumulate()
int main()
{
using namespace std;
vector<int> vec = { 4, 8, 5, 2, 1, 4, 7, 8, 9, 6, 3, 2 };
cout << accumulate(vec.begin(), vec.end(), 0); //计算vec中元素之和,0为初始值
system("pause");
return 0;
}
10.4
accumulate第三个参数的值的类型,表示容器元素转换为对应的类型,那么如果元素是double,转换为int后精度就会丢失。
10.5
一样,但是char *编译器可能会警告,或许用const char *会更好
10.6
#include <iostream>
#include <vector>
#include <algorithm> //fill_n
int main()
{
using namespace std;
vector<int> vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (auto x : vi)
cout << x << "\t";
fill_n(vi.begin(), vi.size(), 0); //把vi中所有元素的值设为0
for (auto x : vi)
cout << x << "\t";
system("pause");
return 0;
}
10.7
a vec是空的,使用copy时要确保至少与输入队列同样多的元素
修改为:copy(lst.cbegin(),lst.cend(),back_iterator(vec));
b 虽然是没错,但是也没任何一样,.size()是0,因为里面没有元素,reservr只是分配预存空间,不添加元素
修改为:vec.resize()或者是fill_n(back_iterator(vec),10,0);
10.8
back_iterator是定义在iterator文件里的,而且算法只是执行这一过程,所以与算法无关。
10.9
#include <iostream>
#include <vector>
#include <algorithm> //sort unique
#include <string>
void elimDups(std::vector<std::string> &vstr)
{
sort(vstr.begin(),vstr.end()); //排序默认小到大
auto u_end = unique(vstr.begin(), vstr.end()); //删除连续重复的元素
vstr.erase(u_end, vstr.end()); //清理空元素
}
int main()
{
using namespace std;
vector<string> vstr = { "111", "222", "333", "444", "222", "333", "555", "777", "111", "888", "666", "666", "999" };
elimDups(vstr);
for (auto s : vstr)
cout << s << endl;
system("pause");
return 0;
}
10.10
个人认为是为了区分算法和成员函数的操作,而且改变后会使迭代器失效
网上找的答案:因为标准库算法操作的迭代器,而不是容器。因此,算法不能(直接)添加或删除元素。(大雾不太明)
10.11
#include <iostream>
#include <vector>
#include <algorithm> //stable_sort unique
#include <string>
bool isShorter(const std::string &s1, const std::string &s2)
{
return s1.size() > s2.size();
}
void elimDups(std::vector<std::string> &vstr,bool (*p)(const std::string &s1,const std::string &s2))
{
sort(vstr.begin(), vstr.end()); //按默认排序
stable_sort(vstr.begin(), vstr.end(), p); //按照谓词p的条件来排序相同长度的单词
auto u_end = unique(vstr.begin(), vstr.end()); //删除连续相同的元素
vstr.erase(u_end, vstr.end()); //清空删除后留下的空白
}
int main()
{
using namespace std;
vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
elimDups(vstr,isShorter);
for (auto s : vstr)
cout << s << endl;
system("pause");
return 0;
}
10.12
#include "../../7.21/7.21/标头.h"
#include <vector>
#include <algorithm> //sort
bool compareIsbn(Sales_data &v1, Sales_data &v2)
{
return v1.isbn().size() < v2.isbn().size();
}
int main()
{
using namespace std;
vector<Sales_data> vsd;
Sales_data temp;
while (read(cin, temp))
vsd.push_back(temp);
sort(vsd.begin(), vsd.end(), compareIsbn);//按照谓词compareIsbn来排序
for (auto &x : vsd)
cout << x.isbn() << endl;
system("pause");
return 0;
}
10.13
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>//partition for_each
bool isShorter(const std::string &s)
{
return s.size() >= 5;
}
void show(const std::string &s)
{
std::cout << s << std::endl;
}
int main()
{
using namespace std;
vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
auto tmp = partition(vstr.begin(), vstr.end(), isShorter); //把一元谓词为真的值放在左边
for_each(vstr.begin(), tmp, show);
system("pause");
return 0;
}
10.14
[](int n,int m){return n+m;}
10.15
[n](int m){reurn n+m;}
10.16
#include <iostream>
#include <vector>
#include <algorithm> //sort unique stable_sort find_if for_each
#include <string>
void elimDups(std::vector<std::string> &vstr)
{
sort(vstr.begin(), vstr.end()); //默认排序
auto u_end = unique(vstr.begin(), vstr.end()); //删除连续相同的元素
vstr.erase(u_end, vstr.end()); //清理空元素
}
void biggies(std::vector<std::string> &s, std::vector<std::string>::size_type sz)
{
elimDups(s);
stable_sort(s.begin(), s.end(), [](const std::string &s1, const std::string &s2){return s1.size() < s2.size(); });//长度相同的单词按二元谓词排序
auto wc = find_if(s.begin(), s.end(), [sz](const std::string &s){return s.size() >= sz; }); //记录第一次大小大于sz的位置
auto count = s.end() - wc; //统计元素尾到wc的位置的距离
std::cout << count << " " << (sz ? "word" : "s") << " of length " << sz << " or longer" << std::endl;
for_each(wc, s.end(), [](const std::string &s){std::cout << s << "\t"; });
std::cout << std::endl;
}
int main()
{
using namespace std;
vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
elimDups(vstr);
for (auto s : vstr)
cout << s << endl;
system("pause");
return 0;
}
10.17
#include "../../7.21/7.21/标头.h"
#include <vector>
#include <algorithm> //sort
int main()
{
using namespace std;
vector<Sales_data> vsd;
Sales_data temp;
while (read(cin, temp))
vsd.push_back(temp);
sort(vsd.begin(), vsd.end(), [](Sales_data &s1, Sales_data &s2){return s1.isbn().size() < s2.isbn().size(); });
for (auto &x : vsd)
cout << x.isbn() << endl;
system("pause");
return 0;
}
10.18
#include <iostream>
#include <vector>
#include <algorithm> //sort unique stable_sort partition for_each
#include <string>
void elimDups(std::vector<std::string> &vstr)
{
sort(vstr.begin(), vstr.end());
auto u_end = unique(vstr.begin(), vstr.end());
vstr.erase(u_end, vstr.end());
}
void biggies(std::vector<std::string> &s, std::vector<std::string>::size_type sz)
{
elimDups(s);
stable_sort(s.begin(), s.end(), [](const std::string &s1, const std::string &s2){return s1.size() < s2.size(); });
auto wc = partition(s.begin(), s.end(), [sz](const std::string &s){return s.size() >= sz; }); //把一元谓词条件为真的元素排序到左边,并返回最后一个条件为真的迭代器
auto count = s.end() - wc;
std::cout << count << " " << (sz ? "word" : "s") << " of length " << sz << " or longer" << std::endl;
for_each(wc, s.end(), [](const std::string &s){std::cout << s << "\t"; });
std::cout << std::endl;
}
int main()
{
using namespace std;
vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
elimDups(vstr);
for (auto s : vstr)
cout << s << endl;
system("pause");
return 0;
}
10.19
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
void elimDups(std::vector<std::string> &vstr)
{
sort(vstr.begin(), vstr.end());
auto u_end = unique(vstr.begin(), vstr.end());
vstr.erase(u_end, vstr.end());
}
void biggies(std::vector<std::string> &s, std::vector<std::string>::size_type sz)
{
elimDups(s);
stable_sort(s.begin(), s.end(), [](const std::string &s1, const std::string &s2){return s1.size() < s2.size(); });
auto wc=stable_partition(s.begin(), s.end(), [sz](const std::string &s){return s.size() < sz; });
auto count = s.end() - wc;
std::cout << count << " " << (sz ? "word" : "s") << " of length " << sz << " or longer" << std::endl;
for_each(wc, s.end(), [](const std::string &s){std::cout << s << "\t"; });
std::cout << std::endl;
}
int main()
{
using namespace std;
vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
biggies(vstr, 5);
system("pause");
return 0;
}
10.20
#include <iostream>
#include <string>
#include <vector>
#include <algorithm> //count_if
int main()
{
using namespace std;
vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
int count = count_if(vstr.begin(), vstr.end(), [](const string &s)->bool{return s.size() >= 6 ? true : false; });//接受一个一元谓词,统计谓词为真的次数
cout << count << endl;
system("pause");
return 0;
}
10.21
auto fun=[&n](){return n?true:false;}
while(fun())
//
10.22
#include <iostream>
#include <vector>
#include <string>
#include <functional> //bind
#include <algorithm> //conut_if
bool isfun(const std::string &s, std::string::size_type n)
{
return s.size() <= n;
}
int main()
{
using namespace std;
using namespace std::placeholders;
vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
cout << count_if(vstr.cbegin(), vstr.cend(), bind(isfun, _1, 6)); //bind返回一个一元谓词,并把6绑定为isfun的第二个参数
system("pause");
return 0;
}
10.23
1+n个,至少一个谓词
10.24
#include <iostream>
#include <string>
#include <vector>
#include <functional> //bind
#include <algorithm> //find_if
bool check_size(std::string::size_type n,const std::string &s)
{
return s.size() < n;
}
int main()
{
using namespace std;
using namespace std::placeholders;
string str = "666666";
vector<int> vi{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
cout << *find_if(vi.begin(), vi.end(), bind(check_size, _1, str)); //返回一个一元谓词,str绑定check_size的string
system("pause");
return 0;
}
10.25
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <functional> //bind
void elimDups(std::vector<std::string> &vstr)
{
sort(vstr.begin(), vstr.end());
auto u_end = unique(vstr.begin(), vstr.end()); //消除重复
vstr.erase(u_end, vstr.end()); //清空消除重复后留下的空余
}
bool check_size(const std::string &s, std::string::size_type n)
{
return s.size() > n;
}
void biggies(std::vector<std::string> &s, std::vector<std::string>::size_type sz)
{
elimDups(s); //排序,消除重复
stable_sort(s.begin(), s.end(), [](const std::string &s1, const std::string &s2){return s1.size() < s2.size(); });//在大小相等的情况下排序
partition(s.begin(), s.end(), bind(check_size,std::placeholders::_1,sz));//再次排序,把大的放左边 bind返回一元谓词,sz绑定第二个参数
for_each(s.begin(), s.end(), [](const std::string &s){std::cout << s << "\t"; });//输出
}
int main()
{
using namespace std;
vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete","the","minecaft","microsoft" };
biggies(vstr, 5);
for (auto s : vstr)
cout << s << endl;
system("pause");
return 0;
}
10.26
iter=back_inserter(vec)返回一个push_back的迭代器
当使用其赋值时相当于调用push_back将元素添加到末尾: iter=9; //相当于vec.push_back(9);需要容器支持push_back
iter=front_inserter(lst)返回一个push_front的迭代器
当使用其赋值时相当于调用push_front将元素添加到首: iter=0; //相当于lst.push_front(0);需要容器支持push_front
iter=inserter(lst,it)返回一个指向lst容器一个位置的迭代器
当使用其赋值时相当于调用inserter(it,val)将元素添加到it指定的位置之前: iter=1; //相当于lst.inserter(it,1);需要容器支持inserter
10.27
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
using namespace std;
vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
vector<string> vstr2;
sort(vstr.begin(), vstr.end());
unique_copy(vstr.begin(), vstr.end(), std::back_inserter(vstr2));
for_each(vstr2.begin(), vstr2.end(), [](const string &s){cout << s << endl; });
system("pause");
return 0;
}
10.28
#include <iostream>
#include <vector>
#include <list>
#include <iterator> //inserater、back_inserater、front_inserter
int main()
{
using namespace std;
vector<int> vi{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
list<int> vi1, vi2, vi3; //不用vector是因为没有push_front
copy(vi.begin(), vi.end(), inserter(vi1, vi1.begin()));//将元素从首开始添加
copy(vi.begin(), vi.end(), back_inserter(vi2));//将元素添加到尾
copy(vi.begin(), vi.end(), front_inserter(vi3));/将元素添加到头
for (auto &x : vi1)
cout << x << "\t";
cout << endl;
for (auto &x : vi2)
cout << x << "\t";
cout << endl;
for (auto &x : vi3)
cout << x << "\t";
cout << endl;
system("pause");
return 0;
}
10.29
#include <iostream>
#include <vector>
#include <fstream>
#include <iterator> //back_inserter
#include <string>
#include <algorithm> //copy
int main(int argc, char **argv)
{
using namespace std;
ifstream ifile(argv[1]);
if (!ifile)
{
cerr << "open file error!";
exit(1);
}
istream_iterator<string> ifstr(ifile), eof; //把流绑定到文件流
vector<string> vstr;
copy(ifstr, eof, back_inserter(vstr));
copy(vstr.begin(), vstr.end(), ostream_iterator<string>(cout, "\n")); //从vstr读取数据并赋值到标准输出流迭代器,格式为 数据+"\n"
ifile.close();
return 0;
}
10.30
#include <iostream>
#include <algorithm> //sort
#include <vector>
#include <iterator> //istream_iterator、ostream_iterator
using namespace std;
int main()
{
istream_iterator<int> itint(cin),eof;
ostream_iterator<int> otint(cout);
vector<int> vi;
while (itint != eof) //or copy(itint,eof,back_insertor(vi));
vi.push_back(*itint++);
sort(vi.begin(), vi.end());
copy(vi.begin(), vi.end(), otint);
system("pause");
return 0;
}
10.31
#include <iostream>
#include <algorithm><span style="white-space:pre"> </span>//copy<span style="white-space:pre"> </span>sort<span style="white-space:pre"> </span>unique_copy
#include <vector>
#include <iterator>
int main()
{
<span style="white-space:pre"> </span>using namespace std;
<span style="white-space:pre"> </span>istream_iterator<int> itint(cin), eof;
<span style="white-space:pre"> </span>vector<int> vi;
<span style="white-space:pre"> </span>copy(itint, eof, back_inserter(vi));
<span style="white-space:pre"> </span>sort(vi.begin(), vi.end());
<span style="white-space:pre"> </span>unique_copy(vi.begin(), vi.end(), ostream_iterator<int>(cout,"\t"));
<span style="white-space:pre"> </span>system("pause");
<span style="white-space:pre"> </span>return 0;
}
10.32
#include "Sales_item.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <numeric> //accumulate
int main()
{
using namespace std;
istream_iterator<Sales_item> sit(std::cin),eof;
vector<Sales_item> vs;
copy(sit, eof, back_inserter(vs));
sort(vs.begin(), vs.end(), [](const Sales_item &s1, const Sales_item &s2){return s1.isbn < s2.isbn; });
for (auto beg = vs.begin(), tmp = beg; beg != vs.end(); beg = tmp) //beg和tmp用于记录相同的元素的范围
{
tmp = find_if(beg, vs.end(), [beg](const Sales_item &s){return s.isbn != beg->isbn; }); //找到范围,(beg,tmp]之间的元素同名的(isbn值)
accumulate(beg, tmp, Sales_item(beg->isbn)); //初始值为0的Sales_item对象
}
for (auto &x : vs)
cout << x << endl;
system("pause");
return 0;
}
10.33
#include <iostream>
#include <fstream>
#include <iterator> //istream_iterator、ostream_iterator
#include <algorithm> //for_each
int main(int argc, char **argv)
{
using namespace std;
ifstream ifile(argv[1]);
if (!ifile)
{
cerr << "open file error!";
exit(1);
}
ofstream of1(argv[2]),of2(argv[3]);
if ((!of1)&&(!of2))
{
cerr << "open file error!1";
exit(2);
}
istream_iterator<int> itf(ifile), eof;
ostream_iterator<int> otf1(of1," "),otf2(of2,"\n");
for_each(itf, eof, [&otf1, &otf2](int i){*(i % 2 ? otf1 : otf2)++ = i; });
//相当于:
/*int t;
while (itf != eof)
{
if ((t = *itf++) % 2)
*otf1++ = t;
else
*otf2++ = t;
}*/
system("pause");
return 0;
}
10.34
#include <iostream>
#include <vector>
int main()
{
using namespace std;
vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (auto beg = vec.crbegin(); beg != vec.crend(); ++beg) //crebgin返回尾迭代器 crend返回首前迭代器
cout << *beg;
system("pause");
return 0;
}
10.35
#include <iostream>
#include <vector>
int main()
{
using namespace std;
vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (auto beg = vec.cbegin(); beg != vec.cend(); ++beg)
cout << *beg;
system("pause");
return 0;
}
10.36
#include <iostream>
#include <list>
int main()
{
using namespace std;
list<int> li{ 1, 0, 6, 3, 5, 5, 2, 3, 0, 8, 1, 0, 5 };
cout << *find(li.rbegin(), li.rend(), 0);
system("pause");
return 0;
}
10.37
#include <iostream>
#include <vector>
#include <list>
int main()
{
using namespace std;
vector<int> vi{ 1,2,3,4,5,6,7,8,9};
list<int> li(vi.crbegin() + 2, vi.crend() - 2); //(3,7]
/*list<int> li;
copy(vi.crbegin() + 2, vi.crbegin() + 7, back_inserter(li));*/
for (auto x : li)
cout << x << "\t";
system("pause");
return 0;
}
10.38
input iterator:==、!=、++、等号右边*n、->
output iterator:++,等号左边*n
forward iterator:==、!=、++、*n、->
bidirectional iterator:==、!=、++、*n、->、--
random-access iterator:==, !=、 <、<=、 >、>=、++、--、+、+=、-、-=、-(两个迭代器)、*、->、iter[n] == * (iter + n)
10.39
list属于bidirectional、vector属于random-access
10.40
copy需要一对输入迭代器和一个输出迭代器
reverse需要一对方向迭代器
unique需要一对向前迭代器
10.41
迭代器beg到end中的old_val替换为new_val
迭代器beg到end中谓词pred为真的替换为new_val
迭代器beg到end中出现old_val时,添加new_val到dest
迭代器beg到end中谓词pred为真时,添加new_val到dest
10.42
#include <iostream>
#include <list>
#include <string>
void elimDups(std::list<std::string> &vstr)
{
vstr.sort();
vstr.unique();
}
int main()
{
using namespace std;
list<string> vstr = { "111", "222", "333", "444", "222", "333", "555", "777", "111", "888", "666", "666", "999" };
elimDups(vstr);
for (auto s : vstr)
cout << s << endl;
system("pause");
return 0;
}