标准库组织
标准库的功能都定义在std命名空间下面
Vector
允许随机访问,可以利用索引直接访问一个元素,
Deque
是double-ended queue的缩写,是一个动态数组,可以向两端发展,在头部和尾部插入元素都非常迅速,在中间插入元素比较费时。
#include <iostream>
#include <deque>
using namespace std;
int main(int argc, char const *argv[])
{
deque<double> coll;
// 在头部插入数据
for (size_t i = 0; i <= 6; i++)
{
coll.push_front(i*1.1);
}
for (size_t i = 0; i < coll.size(); i++)
{
cout<<coll[i]<<endl;
}
system("pause");
return 0;
}
Array
一个array对象是固定大小的array,不可以改变元素个数,只能改变元素值,必须在建立时就指定大小,array可以随机访问。
#include <iostream>
#include <string>
#include <array>
using namespace std;
int main(int argc, char const *argv[])
{
array<string,5> col{"hello","world"};
for (size_t i = 0; i < col.size(); i++)
{
cout<<col[i]<<endl;
}
system("pause");
return 0;
}
List
由双向链表实现,list不能随机访问,比vector和deque慢。
#include <iostream>
#include <string>
#include <list>
using namespace std;
int main(int argc, char const *argv[])
{
list<char> coll;
for (char c='a';c<='z';++c)
{
coll.push_back(c);
}
for (auto elem:coll)
{
cout<<elem<<" ";
}
// 另一种循环方式
while (!coll.empty())
{
cout<<coll.front()<<" ";
coll.pop_front();
}
system("pause");
return 0;
}
set
元素依据value自动排序,每个元素只出现 一次,不允许重复
Multiset
和set唯一的区别是预算年度可以重复
// #include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
int main()
{
multiset<string> cities{
"Braunscheig", "Hanover", "Frankfurt", "New York", "Chicago", "Toronto", "Paris", "Frankfurt"};
for (const auto &elem : cities)
{
cout<<elem<<" ";
}
cout<<endl;
// 插入元素
cities.insert({"London","Munich","Hanover","Braunschweig"});
for (const auto &elem : cities)
{
cout<<elem<<" ";
}
cout<<endl;
system("pause");
return 0;
}
Map
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
int main()
{
multimap<int,string> coll;
coll={{5,"tagged"}
,{2,"a"}
,{1,"this"}
,{4,"of"}
,{6,"target"}
,{1,"is"}
,{3,"multimap"}};
// kry必须是常量
system("pause");
return 0;
}
unordered_map
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <string>
using namespace std;
int main()
{
unordered_map<string,double> coll{{"tim",9.9}
,{"struppi",11.77}};
for(pair<const string,double>& elem:coll )
{
elem.second*=elem.second;
}
for(const auto& elem:coll)
{
cout<<elem.first<<":"<<elem.second<<endl;
}
system("pause");
return 0;
}
关联数组
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <string>
using namespace std;
int main()
{
// 可以看成是一种关联数组
// 索引非整数
unordered_map<string,float> coll;
coll["VAT1"]=0.16;
coll["VAT2"]=0.07;
coll["Pi"]=3.1415;
// 更改值
coll["VAT1"]+=0.03;
cout<<"VAT difference:"<<coll["VAT1"]-coll["VAT2"]<<endl;
system("pause");
return 0;
}
迭代器
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <string>
#include <vector>
#include <list>
using namespace std;
int main()
{
vector<int> nums={4,3,2,7,8,2,3,1};
list<char> coll;
for (char c='a';c<='z';++c)
{
coll.push_back(c);
}
// 遍历所有元素
// 这是一个常量指针
// 不可以使用它对变量进行修改
list<char>::const_iterator pos;
for (pos=coll.begin();pos!=coll.end();++pos)
{
cout<<*pos<<" ";
}
cout<<endl;
// 换种遍历方式
for(auto elem:coll)
{
cout<<elem<<" ";
}
system("pause");
return 0;
}
#include <iostream>
#include <set>
using namespace std;
int main()
{
// typedef std::set<int> IntSet;
// IntSet coll;
// // 随意插入数据
// coll.insert(3);
// coll.insert(1);
// coll.insert(5);
// coll.insert(4);
// coll.insert(1);
// coll.insert(6);
// coll.insert(2);
// // 打印所有的元素
// IntSet::const_iterator pos;
// // 这个类型有特定的排布顺序 默认按照递增顺序排序
// for (pos=coll.begin();pos!=coll.end();++pos)
// {
// std::cout<<*pos<<' ';
// }
// std::cout<<endl;
typedef std::set<int,greater<int>> IntSet;
IntSet coll;
// 随意插入数据
coll.insert(3);
coll.insert(1);
coll.insert(5);
coll.insert(4);
coll.insert(1);
coll.insert(6);
coll.insert(2);
// 打印所有的元素
IntSet::const_iterator pos;
// 现在是按照降序排列
for (pos=coll.begin();pos!=coll.end();++pos)
{
std::cout<<*pos<<' ';
}
std::cout<<endl;
system("pause");
return 0;
}
#include <iostream>
#include <set>
using namespace std;
int main()
{
typedef std::set<int> IntSet;
IntSet coll;
// 可以这样插入元素
coll.insert({3,1,5,4,1,6,2});
// 但是不可以使用push_back或push_front 因为set不允许你指定新元素的位置
system("pause");
return 0;
}
#include <iostream>
#include <set>
#include <unordered_set>
using namespace std;
int main()
{
// 遍历无序的unordered_set
std::unordered_multiset<int> coll;
// insert
coll.insert({1,3,5,7,11,13,17,19,23,27,1});
//
for(auto elem:coll)
{
std::cout<<elem<<' ';
}
std::cout<<endl;
coll.insert(25);
for(auto elem:coll)
{
std::cout<<elem<<' ';
}
std::cout<<endl;
system("pause");
return 0;
}
前向迭代器 | 只能以累加操作符先前迭代 | forward_list unordered_set unordered_multiset unordered_map unordered_multimap |
双向迭代器 | 以递增或递减运算来进行前进后退 | list set multiset map multmap |
随机访问迭代器 | 提供迭代器算术运算的必要操作符,可以+-可以使用>< | vector deque array string |
算法
#include <iostream>
#include <set>
#include <unordered_set>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
// 迭代器种类
// 前向迭代器
// 双向迭代器
// 随机访问迭代器
vector<int> coll={2,5,4,1,6,3};
// 查找最大值和最小值 返回地址
// 返回的是一个地址,如果不适用auto那么应该使用
// vector<int>::const_iterator minpos=
auto minpos=min_element(coll.cbegin(),coll.cend());
cout<<"min: "<<*minpos<<endl;
auto maxpos=max_element(coll.cbegin(),coll.cend());
cout<<"max: "<<*maxpos<<endl;
// 排序
// 这里不允许使用cbegin和cend,因为sort会改动元素的value
sort(coll.begin(),coll.end());
// 找到第一个3
// 如果没有找到返回指向范围的末端
auto pos3=find(coll.begin(),coll.end(), // range
3 // value
);
// 从pos3到end范围内的元素翻转
// 同样对元素进行了修改,所以不能使用cbegin,cend
reverse(pos3,coll.end());
// 打印所有元素
for(auto elem:coll)
{
cout<<elem<<' ';
}
cout<<endl;
system("pause");
return 0;
}
#include <iostream>
#include <set>
#include <unordered_set>
#include <algorithm>
#include <vector>
#include <list>
using namespace std;
int main()
{
list<int> coll;
for(int i=20;i<=40;i++)
{
coll.push_back(i);
}
// 找到3
// 此时查找失败 于是返回区间结束的位置end() 赋值给pos3
auto pos3=find(coll.begin(),coll.end(),3);
// 翻转
// 相当于传入end,end是一个空区间
reverse(pos3,coll.end());
// 找到25到35的位置
list<int>::iterator pos25,pos35;
//
pos25=find(coll.begin(),coll.end(),
25);
pos35=find(coll.begin(),coll.end(),
35);
// 开区间,并不包含35 所以仅仅找到34
cout<<"max: "<<*max_element(pos25,pos35)<<endl;
// 想处理最后一个元素,必须把该元素的下一位置出给算法
cout<<"max: "<<*max_element(pos25,++pos35)<<endl;
// 这个是链表list,所以只能用++来取得下一个位置
// 如果是随机访问迭代器,vector或者deque可以被使用pos35+1 因为随机访问迭代器允许迭代器算数计算
// cout<<"max: "<<*max_element(pos25,coll.end())<<endl;
cout<<"min: "<<*min_element(pos25,pos35)<<endl;
// cout<<"min: "<<*min_element(pos25,coll.end())<<endl;
// 如果不知道有效的区间,不确定哪个元素在前那个元素在后
// 可以使用<来进行检查 前提 是随机访问迭代器才可以
// 如果不是随机访问迭代器
auto pos=find_if(coll.begin(),coll.end(),
[](int i){
return i==25||i==35;
});
if (pos==coll.end())
{
// no element with value 25 or 35 found
}
else if(*pos==25)
{
// 25先出现
pos25=pos;
pos35=find(++pos,coll.end(),
35);
}
else
{
pos35=pos;
pos25=find(++pos,coll.end(),
25);
}
system("pause");
return 0;
}
#include <iostream>
#include <set>
#include <unordered_set>
#include <algorithm>
#include <vector>
#include <list>
using namespace std;
int main()
{
// 处理多重区间
// 有算法需要同时处理多重区间
// 必须设置第一个区间的起点和终点
// equal 从头开始逐一比较coll1和coll2的所有元素
// if (equal(coll1.begin(),coll1.end()),
// coll2.begin())
// 这时需要注意比较coll1和coll2中的元素,所以coll2需要的元素数量间接由coll1决定
list<int> coll1={1,2,3,4,5,6,7,8,9};
vector<int> coll2;
// 扩容
// resize改变coll2的元素个数
coll2.resize(coll1.size());
// 将coll1 copy 到 coll2
copy(coll1.cbegin(),coll1.cend(),
coll2.begin());
system("pause");
return 0;
}
迭代器适配器
C++标准库提供了数个预定义点的特殊迭代器,也就是迭代器适配器
安插型迭代器
insert iterator可以是算法以安插方式而非覆写方式运作。使用它可以解决算法的目标空间不足的问题,它会促使目标区间的大小按需求成长。
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <list>
#include <deque>
#include <set>
using namespace std;
int main()
{
list<int> coll1={1,2,3,4,5,6,7,8,9};
// copy
// back_inserter安插于容器最末端,内部调用push_back
// 在容器末端插入元素,仅仅提供push_back的容器中back_insert才会派上用场
// vector deque list string
vector<int> coll2;
copy(coll1.cbegin(),coll1.cend(),
back_inserter(coll2));
// 安插于容器最前端
// 内部调用push_front 将元素安插于容器最前端
// 但是反转了元素的安插顺序
// 只能用于提供有push_front的容器
// deque list forward_list
deque<int> coll3;
copy(coll1.cbegin(),coll1.cend(),
front_inserter(coll3));
// 在所指位置前方插入元素
set<int> coll4;
copy(coll1.cbegin(),coll1.cend()
,inserter(coll4,coll4.begin()));
system("pause");
return 0;
}
串流迭代器
Stream iterator用来读写stream,
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <list>
#include <deque>
#include <set>
using namespace std;
int main()
{
vector<string> coll;
// 会产生一个可从 标准输入串流(standard input stream) cin 读取数据的stream iterator
// template实参string表示这个stream iterator专门读取这种类型的元素
copy(istream_iterator<string>(cin), // star
// 调用istream iterator的默认构造函数 产生一个代表 串流结束符的迭代器 代表不能再从中读取任何东西
istream_iterator<string>(), //end
back_inserter(coll));
// sort
sort(coll.begin(),coll.end());
unique_copy(coll.cbegin(),coll.cend(),
ostream_iterator<string>(cout,"\n"));
system("pause");
return 0;
}