c++primer 10.26-10.42
10.26
back_inserter 是固定在尾后迭代器之前插入一个元素后返回这个元素的得带器,之后赋值
例如
vector<int> = {1,2,3,4};
//在尾后迭代器之前插入元素并返回该元素的迭代器
//1,返回该位置的迭代器
auto iter = back_inserter(vec);
//2,赋值
*iter=0;
front_inserter是在首元素之前插入元素,会将元素逆序
inserter是在给定位置之前插入元素,注意,迭代器一直是指定位置
例如
list<int> lst1={1,2,3,4};
//这里的begin迭代器在插入第一个元素之后已经不是首迭代器,但是再次插入依旧使用这个迭代器所以不会逆序
copy(lst1.cbegin(),lst1.cend(),inserter(lst3,lst3.begin()));
cout<<"lst3中的内容"<<endl;
for(auto c:lst3){
cout<<c<<" ";
}
cout<<"--------------------"<<endl;
10.27
这里要注意两个点
1,在对元素用unique系列进行去重的时候,首要要对容器内元素进行排序,若不排序,unique只会对相邻元素进行去重
2,排序的时候要用begin()与end()不能用cbegin()与cend(),否则编译就会出现问题。
#include <iostream>
#include<list>
#include<vector>
#include<numeric>
#include<algorithm>
#include<functional>
using namespace std;
int main()
{
vector<string> vec1={"mmm","xxx","mmm","xxx","sss"};
list<string> lst4;
//先排序再去重复
sort(vec1.begin(),vec1.end());
unique_copy(vec1.cbegin(),vec1.cend(),back_inserter(lst4));
for(auto c: lst4){
cout<<c<<" ";
}
cout<<endl;
return 0;
}
10.28
//这里要注意vector是数组,不支持push_front 也就不支持front_inserter
#include <iostream>
#include<list>
#include<vector>
#include<numeric>
#include<algorithm>
#include<functional>
using namespace std;
int main()
{
vector<int> vec2={1,2,3,4,5,6,7,8,9};
vector<int> copy_vec21,copy_vec22;
list<int> copy_vec_list;
//用back_inserter拷贝
copy(vec2.cbegin(),vec2.cend(),back_inserter(copy_vec21));
cout<<"用back_inserter拷贝的copy_vec21"<<endl;
for(auto c :copy_vec21){
cout<<c<<" ";
}
cout<<endl;
//用inserter拷贝
copy(vec2.cbegin(),vec2.cend(),inserter(copy_vec22,copy_vec22.begin()));
cout<<"用inserter拷贝的copy_vec22"<<endl;
for(auto c :copy_vec22){
cout<<c<<" ";
}
cout<<endl;
//用front_inserter拷贝
//vector不支持push_front,也就不支持front_inserter
copy(vec2.cbegin(),vec2.cend(),front_inserter(copy_vec_list));
cout<<"用inserter拷贝的copy_vec_list"<<endl;
for(auto c :copy_vec_list){
cout<<c<<" ";
}
cout<<endl;
return 0;
}
10.29
#include <iostream>
#include<fstream>
#include<iterator>
#include<vector>
#include<numeric>
#include<algorithm>
#include<functional>
using namespace std;
int main()
{
//练习10.29
//文件输入流读入数据
ifstream ifs_10_29("C:\\study\\c++test\\endless.txt");
//文件输入流的首尾迭代器
istream_iterator<string> isi(ifs_10_29);
istream_iterator<string> isi_end;
//构造数组
vector<string> vec_10_29(isi,isi_end);
ostream_iterator<string > cout_iter(cout," ");
copy(vec_10_29.cbegin(),vec_10_29.cend(),cout_iter);
cout<<endl;
return 0;
}
10.30
基本与29题一样
#include <iostream>
#include<fstream>
#include<iterator>
#include<vector>
#include<numeric>
#include<algorithm>
#include<functional>
using namespace std;
int main()
{
//练习10.30
//1,从文件中读入整数shulie
ifstream ifs_10_30("C:\\study\\c++test\\number.txt");
//文件输入的流迭代器
istream_iterator<int> ii_30(ifs_10_30);
istream_iterator<int> ii_30_end;
//构造数组容器
vector<int> vec_20_30(ii_30,ii_30_end);
sort(vec_20_30.begin(),vec_20_30.end());
//创建cout的迭代器
ostream_iterator<int> cout_iter_30(cout," ");
copy(vec_20_30.cbegin(),vec_20_30.cend(),cout_iter_30);
cout<<endl;
return 0;
}
10.31
30题在copy后用上unique_copy,也就是
copy(vec_20_30.cbegin(),vec_20_30.cend(),cout_iter_30);
改成
unique_copy(vec_10_31.begin(),vec_10_31.end(),cout_iter_31);
10.32
#include <iostream>
#include<fstream>
#include<istream>
#include<iterator>
#include<vector>
#include<numeric>
#include<algorithm>
#include<functional>
using namespace std;
/**
*iosteam迭代器
*使用算法操作流迭代器
*ostream_iterator的操作
*
**/
int main()
{
//10.32
//创建输入流迭代器和类容器
istream_iterator<Sales_item> iter_32(cin);
istream_iterator<Sales_item> end_32;
vector<Sales_item> vec_32;
//使用迭代器将信息写入容器
while(iter_32!=end_32){
vec.push_back(*iter_32++);
}
//将信息排序(compareIsbn是对bookNo进行操作的函数)
sort(vec_32.begin(),vec_32.end(),compareIsbn);
//将相同编号的交易记录加起来,到下一条不同编号的记录的时候进行输出
for(auto it_32 = vec_32.begin(),last_32=it_32;
it_32!=vec_32.end();
it_32 = last_32){
last = find_if(it_32,vec_32.cend(),[last_32](const Sales_item &item){return item.isbn()!=last->isbn();});
cout<<accumulate(it_32,last,Sales_item(last_32->isbn()))<<endl;
}
return 0;
}
10.33
注意步骤
i#include <iostream>
#include<fstream>
#include<istream>
#include<ostream>
#include<iterator>
#include<algorithm>
#include<functional>
using namespace std;
int main()
{
//10.33
//1,创建文件输入流对象和首尾迭代器
ifstream ifs_33("C:\\study\\c++test\\number.txt");
istream_iterator<int> in_33(ifs_33);
istream_iterator<int> end_33;
//2,创建两个文件输出流对象并关联到文件
ofstream ofs_o("C:\\study\\c++test\\odd.txt");
ofstream ofs_e("C:\\study\\c++test\\even.txt");
//3,分别创建对应输出流的流首迭代器
ostream_iterator<int> out_o_33(ofs_o," ");
ostream_iterator<int> out_e_33(ofs_e," ");
//4,for_each语句进行判别操作
for_each(in_33,end_33,[&out_o_33,&out_e_33]( int i){
if(i & 0x1){
*out_e_33=i;
i++;
}else{
*out_o_33=i;
i++;
}
});
return 0;
}
10.34:大体与书上类似(反向迭代器逆序打印)
#include <iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<list>
#include<string>
using namespace std;
int main()
{
cout<<"reverse_iterator show:";
vector<int> vec_34={1,2,4,5,6,7,8,9};
for(auto c=vec_34.crbegin();c!= vec_34.crend();c++){
cout<<*c<<" ";
}
cout<<endl;
return 0;
}
10.35:
这里耍了一个小聪明,因为我并确定vector首迭代器之前还能不能用一个迭代器指代,事实证明可以
#include <iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<list>
#include<string>
using namespace std;
int main()
{
cout<<"nomal iterator show:";
vector<int> vec_35={1,2,4,5,6,7,8,9};
auto iter_35=vec_35.cend()-1;
auto iter_35_f=vec_35.begin()-1;
while(iter_35!=iter_35_f){
cout<<*iter_35<<" ";
iter_35--;
}
return 0;
}
靠谱一点的main函数应该是这样的
void main(){
cout<<"nomal iterator show:";
vector<int> vec_35={1,2,4,5,6,7,8,9};
//因为cend()为尾后迭代器,指向容器内最后一个数的后面,所以要普通迭代器循环的时候指向最后一个元素就可以
for(auto iter_35 = vec_35.cend()-1;true;--iter_35){
cout<<*iter_35<<" ";
if(iter_35==vec_35.cbegin()){
break;
}
}
return 0;
}
10.36
#include <iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<list>
#include<string>
using namespace std;
int main()
{
//10.36
list<int > lst_36={1,2,3,4,50,0,2,3,0,50};
//使用反相迭代器
auto iter_36=find(lst_36.crbegin(),lst_36.crend(),0);
cout<<*iter_36<<endl;
return 0;
}
验证一下的话可以用distance函数 显示一下从头数是第几个元素
cout<<distance(iter_36,lst_36.crend())<<endl;
10.37
#include <iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<list>
#include<string>
using namespace std;
int main()
{
//10.37
vector<int> vec_37={1,2,3,4,5,6,7,8,9,10};
list<int> lst_37;
copy(vec_37.crbegin()+3,vec_37.crend()-2,back_inserter(lst_37));
for(auto c:lst_37){
cout<<c<<" ";
}
return 0;
}
10.38
五种迭代器:
1输入迭代器:支持判定(== !=)推进自己前置后置的运算(++),解引用;适用于顺序访问。 适用于单遍扫描
2输出迭代器:支持自身递增递减的操作,解引用,单遍扫描
3前向迭代器:在序列中沿一个方向移动,支持所有输入和输出迭代器的操作,支持多次读写同一个元素。
4双向迭代器:支持前向迭代器的所有操作,支持前置后置的(--)
5随机迭代器:支持上双向迭代器的所有操作,还支持比较相对位置,计算相对位置差值,计算整数加减(+=,-=),(iter[n])和(iter[n])是相同的操作;
10.39:
list是双向链表 双向迭代器
vector是数组,随机迭代器
10.40
copy三个参数,前两个为输入迭代器,最后一个为输出迭代器
reverse是反转函数 双向迭代器的
unique去重复函数,单向的 是前向迭代器
10.41
从beg遍历到end,用new_val替换old_val
从beg遍历到end,遇到pred为true就用new_val替换
从beg遍历到end,用new_val替换old_val,并将其拷贝到dest
从beg遍历到end,遇到pred为true就用new_val替换,并将其拷贝到dest
10.42
只是改改容器而已 略