小结array、vector、set、list、map、queue、stack
顺序容器:vector、list、queue
关联容器:map、set
vector存储结构式数组,其他的存储结构为链表
list和vector的区别:vector相当于封装了数组,可以改变大小,它使用的是连续的地址,能够用[]操作符访问,而list相为链表形式,不能用[]访问。由此,vector尾插、查找较快,list插入数据较快。
map和set的区别:两者使用了非常高效的平衡检索二叉树,它插入删除小路比其他序列容器高是因为不用做内存的拷贝和移动,而直接替换指向节点的指针即可。set中不包含重复的数据,且只包含key,而map含有key和其对应的value。
map和hash_map的区别是hash_map使用了hash算法来加快查找过程,但需要更多内存来存放这些hash桶元素。
<array>
固定大小、线性顺序、顺序存储
array::begin和array::end
array<int,5> myarray = { 2, 16, 77, 34, 50 };
for ( auto it = myarray.begin(); it != myarray.end(); ++it )
std::cout << ' ' << *it; //输出结果为 2 16 77 34 50
2 16 77 34 50
array::begin和array::rend 为逆序
array<int,4> myarray = {4, 26, 80, 14} ;
for ( auto rit=myarray.rbegin() ; rit < myarray.rend(); ++rit )
std::cout << ' ' << *rit; //输出结果为 14 80 26 4
14 80 26 4
array::front和array::back
array<int,3> myarray = {5, 19, 77};
cout << "front is: " << myarray.front() << std::endl; // 5
cout << "back is: " << myarray.back() << std::endl; // 77
myarray.back() = 50;
for ( int& x : myarray ) std::cout << ' ' << x; // 5 19 50
5 19 50
array::at、[]和size
array<int,10> myarray;
for (int i=0; i<10; i++) myarray.at(i) = i+1; //1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
for (int i=0; I<myarray.size(); i++) myarray.at[i] = i; // 0 1 2 3 4 5 6 7 8 9
for (int i=0; I<myarray.size(); i++) myarray.at[i] = i; // 0 1 2 3 4 5 6 7 8 9
ps. sizeof计算所占内存字节数,如上面的myarray,sizeof(myarray)=40,因为每个int所占的内存字节数为4,总共10个int
array::empty //判断数组是否为空
array::fill
array<int,6> myarray;
myarray.fill(5); //5 5 5 5 5 5
5 5 5 5 5 5
array::swap()
array<int,5> first = {10, 20, 30, 40, 50};
array<int,5> second = {11, 22, 33, 44, 55};
first.swap (second); //first: 11 22 33 44 55. second: 10 20 30 40 50
first: 11 22 33 44 55. second: 10 20 30 40 50
<vector>
可动态修改大小,相邻存储
基本用法如上:begin(), end(), rbegin(), rend(), front(), back(), size(), empty(), 操作符[], at(), swap()
不能在头部进行增加删除
vector::resize 和 vector::push_back
vector<int> myvector;
for (int i=1;i<10;i++) myvector.push_back(i);
myvector.resize(5);
myvector.resize(8,100);
myvector.resize(12); // 1 2 3 4 5 100 100 100 0 0 0 0
1 2 3 4 5 100 100 100 0 0 0 0
vector::pop_back //删除最后一个元素,获取最后一个元素是back()
vector::find和distance //查找元素位置
vector<int> v={1,2,3,4,5}
auto idx=find(v.begin(),v.end(),3);
int pos=distance(v.begin(),idx); //pos=2
合并两个vector
vector<int>left,right,res;
//insert方式
res.insert(res.end(),left.begin(),left.end());
res.insert(res.end(),right.begin(),right.end());
//merge方式
res.resize(left.size()+right.size());
merge(left.begin(),left.end(),right.begin(),right.end(),res.begin());
vector赋值获取一部分元素
vector<int>nums={0,1,2,3,4};
vector<int>nums_left(nums.begin(),nums.begin()+3); //{0,1,2}
vector<int>noms_right(nums.begin()+3,nums.end()); //{3,4}
vector::reverse //逆序
vector <int>myvector={1,2,3}
reverse(myvector.begin(),myvector.end()); //改变原vector :3 2 1
reverse_copy(BidirectionalIterator first,BidirectionalIterator last,OutputIterator result)//复制到新的vector
vector::count//统计元素个数
int num = count(vec.begin(),vec.end(),cnt);//cnt在vec中出现的次数
vector::insert
vector<int> myvector (3,100);
vector<int>::iterator it;
it = myvector.begin();
it = myvector.insert ( it , 200 );
myvector.insert (it,2,300);
// "it" no longer valid, get a new one:
it = myvector.begin();
vector<int> anothervector (2,400);
myvector.insert (it+2,anothervector.begin(),anothervector.end());
int myarray [] = { 501,502,503 };
myvector.insert (myvector.begin(), myarray, myarray+3); //myvector contains: 501 502 503 300 300 400 400 200 100 100 100
myvector contains: 501 502 503 300 300 400 400 200 100 100 100
vector::emplace
vector<int> myvector = {10,20,30};
auto it = myvector.emplace ( myvector.begin()+1, 100 );
myvector.emplace ( it, 200 );
myvector.emplace ( myvector.end(), 300 ); // 10 200 100 20 30 300
10 200 100 20 30 300
vector::emplace_back
vector<int> myvector = {10,20,30};
myvector.emplace_back (100); // 10 20 30 100
10 20 30 100
vector::erase
// erase the 6th element
myvector.erase (myvector.begin()+5);
// erase the first 3 elements:
myvector.erase (myvector.begin(),myvector.begin()+3);
vector::capacity //能容纳的最大个数
ps.size值容器当前有的元素的最大个数,capacity指分配存储空间前能够存储的最大个数(预存储个数大小)
vector::reserve //调整容器的大小
ps.调用resize(n)后,容器的size为n;调用reserve(n)后,如果n>capacity,capacity的值为n,若n<capacity,则capacity为原值
容器调用resize后,所有的空间都已经初始化了,可直接访问,而reserve预分配的空间未被初始化,所以不可访问。
vector::shrink_to_fit
vector<int> myvector (100); //capacity of myvector: 100
myvector.resize(10); //capacity of myvector: 100
myvector.shrink_to_fit(); //capacity of myvector: 10
capacity of myvector: 100
myvector.resize(10); //capacity of myvector: 100
myvector.shrink_to_fit(); //capacity of myvector: 10
vector::assign
myvector.assign (7,100); // 7 ints with a value of 100
vector::data
vector<int> myvector (5);
int* p = myvector.data();
*p = 10;
++p;
*p = 20;
p[2] = 100; //myvector contains: 10 20 0 100 0
vector<string> vec={"c++","php","java"};
string *pstr=vec.data();
for(size_t n=0;n<vec.size();n++,pstr++){
cout<<"vec.data() is "<<*pstr<<endl;
}//vec.data() is c++
vec.data() is php
vec.data() is java
myvector contains: 10 20 0 100 0
vector<string> vec={"c++","php","java"};
string *pstr=vec.data();
for(size_t n=0;n<vec.size();n++,pstr++){
cout<<"vec.data() is "<<*pstr<<endl;
}//vec.data() is c++
vec.data() is php
vec.data() is java
vector::clear //清除vector中的所有元素
<list>
基本方法如上:begin(), end(), begin(), rend(), empty(), size(), insert(), erase(), swap(), clear(), emplace(),merge(), reverse()
可在两端进行增加删除
list::emplace_front
list< std::pair<int,char> > mylist;
mylist.emplace_back(10,'a');
mylist.emplace_back(20,'b');
mylist.emplace_back(30,'c');
for (auto& x: mylist)
cout << " (" << x.first << "," << x.second << ")"; //mylist contains: (30,c) (20,b) (10,a)
mylist contains: (30,c) (20,b) (10,a)
list::push_front
list<int> mylist (2,100); // two ints with a value of 100
mylist.push_front (200);
mylist.push_front (300); //300 200 100 100
300 200 100 100
list::pop_front和pop_back //弹出首位元素和末尾元素
list::splice
list<int> mylist1, mylist2;
std::list<int>::iterator it;
for (int i=1; i<=4; ++i)
mylist1.push_back(i); // mylist1: 1 2 3 4
for (int i=1; i<=3; ++i)
mylist2.push_back(i*10); // mylist2: 10 20 30
it = mylist1.begin();
++it; // points to 2
mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4
// mylist2 (empty) splice 移动会改变两个list中的元素
// "it" still points to 2 (the 5th element)
mylist2.splice (mylist2.begin(),mylist1, it);
// mylist1: 1 10 20 30 3 4
// mylist2: 2 将it所指的元素移动到mylist2的起始位置
// "it" is now invalid.
it = mylist1.begin();
advance(it,3); // "it" points now to 30,迭代器增量操作
mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
// mylist1: 30 3 4 1 10 20 感觉splice的操作是移动原本的数据,而不是拷贝
list::remove
int myints[]= {17,89,7,14};
list<int> mylist (myints,myints+4);
mylist.remove(89); // mylist contains: 17 7 14
mylist contains: 17 7 14
list::remove_if
int myints[]= {15,36,7,17,20,39,4,1};
list<int> mylist (myints,myints+8); // 15 36 7 17 20 39 4 1
mylist.remove_if (single_digit); // 15 36 17 20 39 删除只有一位数的数字
mylist.remove_if (is_odd()); // 36 20 删除奇数
list::unique
double mydoubles[]={ 12.15, 2.72, 73.0, 12.77, 3.14,
12.77, 73.35, 72.25, 15.3, 72.25 };
list<double> mylist (mydoubles,mydoubles+10);
mylist.sort(); // 2.72, 3.14, 12.15, 12.77, 12.77,
// 15.3, 72.25, 72.25, 73.0, 73.35
mylist.unique(); // 2.72, 3.14, 12.15, 12.77
// 15.3, 72.25, 73.0, 73.35
mylist.unique (same_integral_part); // 2.72, 3.14, 12.15
// 15.3, 72.25, 73.0
mylist.unique (is_near()); // 2.72, 12.15, 72.25
list::merge
<set>
元素唯一
基本方法如上:begin(), end(), begin(), rend(), empty(), size(), insert(), erase(), swap(), clear(), emplace()
set::find
for (int i=1; i<=5; i++) myset.insert(i*10); // set: 10 20 30 40 50
it=myset.find(20);
myset.erase (it);
myset.erase (myset.find(40)); //myset contains: 10 30 50
myset contains: 10 30 50
set::count
for (int i=1; i<5; ++i) myset.insert(i*3); // set: 3 6 9 12
for (int i=0; i<10; ++i)
{
cout << i;
if (myset.count(i)!=0)
cout << " is an element of myset.\n";
else
cout << " is not an element of myset.\n";
} //统计元素出现次数
0 is not an element of myset.
1 is not an element of myset.
2 is not an element of myset.
3 is an element of myset.
4 is not an element of myset.
5 is not an element of myset.
6 is an element of myset.
7 is not an element of myset.
8 is not an element of myset.
9 is an element of myset.
set::lower_bound和upper_bound
for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90
itlow=myset.lower_bound (30); // ^
itup=myset.upper_bound (60); // ^
myset.erase(itlow,itup); // 10 20 70 80 90
<map>
基本方法如上:begin(), end(), begin(), rend(), empty(), size(), insert(), erase(), swap(), clear(), emplace(),merge(), reverse()
map<char,int> mymap;
mymap['b'] = 100;
mymap['a'] = 200;
mymap['c'] = 300;
for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
std::cout << it->first << " => " << it->second << '\n'; //a => 200 b => 100 c => 300
a => 200 b => 100 c => 300
map::at
map<std::string,int> mymap = {
{ "alpha", 0 },
{ "beta", 0 },
{ "gamma", 0 } };
mymap.at("alpha") = 10;
mymap.at("beta") = 20;
mymap.at("gamma") = 30;
for (auto& x: mymap) {
std::cout << x.first << ": " << x.second << '\n';
} //
lpha: 10
beta: 20
gamma: 30
map::insert
map<char,int> mymap;
mymap.insert ( std::pair<char,int>('a',100) );
mymap.insert ( std::pair<char,int>('z',200) );
pair<map<char,int>::iterator,bool> ret;
ret = mymap.insert ( pair<char,int>('z',500) );
if (ret.second==false) {
std::cout << "element 'z' already existed with a value of " << ret.first->second << '\n';
}
// second insert function version (with hint position):
map<char,int>::iterator it = mymap.begin();
mymap.insert (it, pair<char,int>('b',300)); // max efficiency inserting
mymap.insert (it, pair<char,int>('c',400)); // no max efficiency inserting
// third insert function version (range insertion):
map<char,int> anothermap;
anothermap.insert(mymap.begin(),mymap.find('c'));
//lement 'z' already existed with a value of 200
lement 'z' already existed with a value of 200
mymap contains:
a => 100
b => 300
c => 400
z => 200
anothermap contains:
a => 100
b => 300
<queue>
先进先出
常用方法有:empty(), size(), front(), back(), push(), emplace(), pop(), swap()
<stack>
先进后出
常用方法有:empty(), size(), top(), push(), emplace(), swap()
ps.stack中pop出的是后进入的元素,queue中pop出的是先进入的元素