STL:容器-对象储存器
参考文献《大道至简:C++STL》
- 容器的种类
序列式容器(未排序):vector(动态数组)、deque(双向队列)、list(双向串)
关联式容器(已排序):set、multiset、map、multimap、hash table
容器配接器(以某种STL容器作为底,修改器接口):stack、queue、priority_queue(优先队列)
- 容器的数据结构
#include <iostream>
#include <bitset>
#include <valarray>
#include <string>
using namespace std;
template <typename T> void print(const T& val)
{
cout << val << endl;
}
template <typename T> void print_valarray(const valarray<T>& va)
{
for(int i = 0; i < va.size(); i++)
{
cout << va[i] << " ";
}
cout << endl;
}
int main()
{
/*string*/
string str = "fYg&CT&d^R%5";
print(str);
/*bitset*/
bitset<10> bs1(7);
bitset<10> bs2(string("0101010101"));
print(bs1); //0000000111
print(bs2); //0101010101
/*valarray*/
valarray<int> val1(4);
print_valarray(val1); //0 0 0 0
valarray<int> val2(3, 4);
print_valarray(val2); //3 3 3 3
int arr[] = {4, 2, 6, 1, 8};
valarray<int> val3(arr, sizeof(arr)/sizeof(arr[0]));
print_valarray(val3); //4 2 6 1 8
valarray<int> val4(arr + 1, 4);
print_valarray(val4); //2 6 1 8
val1 = (val2 + val4) * val4;
print_valarray(val1); //10 54 4 88
return 0;
}
- vector
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
template <typename T> void print(const T& val)
{
cout << val << endl;
}
template <typename T> void print_elem(const vector<T>& vt)
{
for(auto cit = vt.begin(); cit != vt.end(); cit++)
{
cout << *cit << " ";
}
cout << endl;
}
bool couif(const string& str)
{
return str.size() > 6 ? true : false;
}
class cs
{
public:
cs(const int& _no, const double& _score):no(_no),score(_score){}
bool operator<(const cs& n) const
{
return no < n.no;
}
friend ostream& operator<<(ostream& out, const cs& c);
int no;
double score;
};
ostream& operator<<(ostream& out, const cs& c)
{
out << "{no:" << c.no << " score:" << c.score << "}";
return out;
}
bool sort_accord_no(const cs& cs1, const cs& cs2)
{
return cs1.no < cs2.no;
}
bool sort_accord_score(const cs& cs1, const cs& cs2)
{
return cs1.score < cs2.score;
}
int main()
{
/*vector*/
vector<string> vstr;
vstr.push_back("F7f^&ft");
vstr.push_back("vUF^5d&ft7");
vstr.push_back("vYFt7f");
print_elem(vstr); //F7f^&ft vUF^5d&ft7 vYFt7f
print((int)vstr.size()); //3
print((int)vstr.capacity()); //4
print(vstr.max_size()); //576460752303423487
vstr.reserve(8);
print((int)vstr.size()); //3
print((int)vstr.capacity()); //8
print(vstr.max_size()); //576460752303423487
vstr.resize(2);
print((int)vstr.size()); //2
print((int)vstr.capacity()); //8
print(vstr.max_size()); //576460752303423487
print_elem(vstr); //F7f^&ft vUF^5d&ft7
vstr.push_back("vYFt7f");
print_elem(vstr); //F7f^&ft vUF^5d&ft7 vYFt7f
print(vstr.front()); //F7f^&ft
print(vstr.back()); //vYFt7f
print(!vstr.empty()); //1
for(int i = 0; i < vstr.size(); i++)
{
print(vstr.at(i));
}
/*
F7f^&ft
vUF^5d&ft7
vYFt7f
*/
while(!vstr.empty())
{
vstr.pop_back();
}
print(vstr.empty()); //1
vstr.push_back("F7f^&ft");
vstr.push_back("vUF^5d&ft7");
vstr.push_back("vYFt7f");
print_elem(vstr);
for_each(vstr.begin(), vstr.end(), print<string>);
int cif = count_if(vstr.begin(), vstr.end(), couif);
print(cif); //2
vector<int> vint = {3, 6, 1, 5, 8, 3, 2};
vector<int>::iterator loc = find(vint.begin(), vint.end(), 1);
print(loc - vint.begin()); //2
loc = find_if(vint.begin(), vint.end(), bind2nd(greater<int>(), 3));
print(loc - vint.begin()); //1
print_elem(vint); //3 6 1 5 8 3 2
vint.insert(vint.begin() + 1, -1);
print_elem(vint); //3 -1 6 1 5 8 3 2
vint.insert(vint.end(), vint.begin() + 2, vint.end());
print_elem(vint); //3 -1 6 1 5 8 3 2 6 1 5 8 3 2
vint.insert(vint.end() - 3, 5, 0);
print_elem(vint); //3 -1 6 1 5 8 3 2 6 1 5 0 0 0 0 0 8 3 2
while (!vint.empty())
{
vint.erase(vint.begin());
print_elem(vint);
}
cs cs1(4, 65.8), cs2(8, 74.9), cs3(2, 69.8), cs4(1, 55.8);
vector<cs> vcs;
vcs.push_back(cs1);
vcs.push_back(cs2);
vcs.push_back(cs3);
vcs.push_back(cs4);
print_elem(vcs); //{no:4 score:65.8} {no:8 score:74.9} {no:2 score:69.8} {no:1 score:55.8}
sort(vcs.begin(), vcs.end());
print_elem(vcs); //{no:1 score:55.8} {no:2 score:69.8} {no:4 score:65.8} {no:8 score:74.9}
sort(vcs.begin(), vcs.end(), sort_accord_score);
print_elem(vcs); //{no:1 score:55.8} {no:4 score:65.8} {no:2 score:69.8} {no:8 score:74.9}
sort(vcs.begin(), vcs.end(), sort_accord_no);
print_elem(vcs); //{no:1 score:55.8} {no:2 score:69.8} {no:4 score:65.8} {no:8 score:74.9}
return 0;
}
- list
list不支持随机存取,没有[]操作符和at()函数
list没有提供容量、空间重新分配等操作函数,每个元素有自己的内存
#include <iostream>
#include <algorithm>
#include <list>
using namespace std;
template <typename T> void print(const T& val)
{
cout << val << endl;
}
template <typename T> void print_elem(const list<T>& val)
{
for(auto cit = val.begin(); cit != val.end(); cit++)
{
cout << *cit << " ";
}
cout << endl;
}
int main()
{
/*list*/
list<double> ldou = {1.9, 2.7, 3.3, 4.9, 5.2, 6.6, 7.3, 8.8, 9.7};
print_elem(ldou);
for_each(ldou.begin(), ldou.end(), print<double>);
ldou.assign(5, 0.0); //重置ldou为5个0
print_elem(ldou); //0 0 0 0 0
ldou = {1.9, 2.7, 3.3, 4.9, 5.2};
list<double> temp = {0.5, 0.6};
ldou.insert(++ldou.begin(), 0.1);
print_elem(ldou); //1.9 0.1 2.7 3.3 4.9 5.2
ldou.insert(ldou.end(), 2, 0.2);
print_elem(ldou); //1.9 0.1 2.7 3.3 4.9 5.2 0.2 0.2
ldou.insert(ldou.begin(), temp.begin(), temp.end());
print_elem(ldou); //0.5 0.6 1.9 0.1 2.7 3.3 4.9 5.2 0.2 0.2
while (!ldou.empty())
{
ldou.erase(ldou.begin());
print_elem(ldou);
}
list<int> l1{1, 2};
list<int> l2(l1);
print_elem(l1);
print_elem(l2);
print(l1 == l2); //1
print(l1 != l2); //0
print(l1 > l2); //0
print(l1 < l2); //0
l1.push_back(1);
l2.push_back(3);
print(l1 == l2); //0
print(l1 != l2); //1
print(l1 > l2); //0
print(l1 < l2); //1
l1 = {5, 2, 4, 3};
l2 = {1, 7, 3};
print_elem(l1);
print_elem(l2);
l1.merge(l2);
print_elem(l1); //1 5 2 4 3 7 3
l1 = {5, 2, 4, 3};
l2 = {1, 7, 3};
l1.merge(l2, greater<>());
print_elem(l1); //5 2 4 3 1 7 3
l1 = {5, 2, 4, 3};
l2 = {1, 7, 3};
l1.sort();
print_elem(l1); //2 3 4 5
l2.sort(greater<>());
print_elem(l2); //7 3 1
l1.remove(3);
print_elem(l1); //2 4 5
l2.remove_if(bind2nd(not_equal_to<int>(), 1));
print_elem(l2); //1
l1 = {5, 2, 4, 3};
l2 = {1, 7, 3};
l1.splice(++l1.begin(), l2);
print_elem(l1); //5 1 7 3 2 4 3
l1 = {5, 2, 4, 3};
l2 = {1, 7, 3};
l1.splice(++l1.begin(), l2, ++l2.begin());
print_elem(l1); //5 7 2 4 3
l1 = {5, 2, 4, 3};
l2 = {1, 7, 3};
l1.splice(++l1.begin(), l2, ++l2.begin(), l2.end());
print_elem(l1); //5 7 3 2 4 3
l1.merge(l2);
print_elem(l1); //1 5 7 3 2 4 3
//对list进行unique时,先sort
l1.sort();
l1.unique();
print_elem(l1); //1 2 3 4 5 7
l1.reverse();
print_elem(l1); //7 5 4 3 2 1
l1.unique(not_equal_to<int>());
print_elem(l1); //7
return 0;
}
- deque
deque与vector具有几乎类似的接口,提供随机存取,动态数组管理,最重要的特征是在两端插入和删除元素
#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;
template <typename T> void print(const T& val)
{
cout << val << " ";
}
template <typename T> void print_elem(const deque<T>& dt)
{
for_each(dt.begin(), dt.end(), print<T>);
cout << endl;
}
int main()
{
/*deque*/
deque<int> dint = {2, 4, 1, 6, 5};
print_elem(dint);
dint.push_front(0);
dint.push_back(0);
print_elem(dint);
dint.pop_front();
dint.pop_back();
print_elem(dint);
deque<int> temp = {1, 2, 4};
temp.swap(dint);
print_elem(temp);
print_elem(dint);
temp.swap(dint);
print_elem(dint);
print(dint > temp); //1
return 0;
}
- set/multiset
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
template <typename T> void print(const T& val)
{
cout << val << " ";
}
template <typename T> void print_elem(const set<T>& st)
{
for_each(st.begin(), st.end(), print<T>);
cout << endl;
}
template <typename T> void print_elem(const multiset<T>& st)
{
for_each(st.begin(), st.end(), print<T>);
cout << endl;
}
int main()
{
/*set/multiset*/
set<int> sint1 = {6, 4, 2, 2, 3, 9, 0};
print_elem(sint1); //0 2 3 4 6 9
multiset<int> msint1 = {6, 4, 2, 2, 3, 9, 0};
print_elem(msint1); //0 2 2 3 4 6 9
print(sint1.size());
print(msint1.size());
print(sint1.max_size());
print(msint1.max_size());
print(sint1.count(2));
print(msint1.count(2));
set<int>::iterator sit = sint1.find(2);
multiset<int>::iterator msit = msint1.find(12);
print(*sit); //2
print(*msit); //7
sit = sint1.lower_bound(2); //大于等于2的第一个数
msit = msint1.lower_bound(3); //大于等于3的第一个数
print(*sit); //2
print(*msit); //3
sit = sint1.upper_bound(2); //大于2的第一个数
msit = msint1.upper_bound(3); //大于3的第一个数
print(*sit); //3
print(*msit); //4
pair<set<int>::iterator, set<int>::iterator> psit = sint1.equal_range(3);
pair<multiset<int>::iterator, multiset<int>::iterator> pmsit = msint1.equal_range(3);
cout << *psit.first << "," << *psit.second << endl;
cout << *pmsit.first << "," << *pmsit.second << endl;
//分别指向大于等于3的第一个数和大于3的第一个数
print_elem(sint1);
print_elem(msint1);
pair<set<int>::iterator, bool> sp1;
sp1 = sint1.insert(2);
print(sp1.second); //0
sp1 = sint1.insert(10);
print(sp1.second); //1
print(distance(sint1.begin(), sp1.first)); //6
multiset<int>::iterator msp1;
msp1 = msint1.insert(2);
msint1.erase(2);
print_elem(msint1); //0 3 4 6 9
set<double, less<double>> s1 = {1, 5, 7, 4};
multiset<double, greater<double>> ms1 = {1, 6, 9, 4};
set<double, less<double>>::key_compare skc1 = s1.key_comp();
multiset<double, greater<double>>::key_compare mskc1 = ms1.key_comp();
print(skc1(2, 3)); //1
print(mskc1(1, 2)); //0
return 0;
}
- map/multimap
#include <iostream>
#include <map>
#include <algorithm>
#include <string>
using namespace std;
#ifndef out
#define out(x) {cout << (x) << " ";}
#endif
#ifndef newline
#define newline() {cout << endl;}
#endif
template <typename Key, typename Val>
void out2nd(const Key& k, const Val& v)
{
out(k);
out(":");
out(v);
newline();
}
template <typename Key, typename Val, typename Comp = less<Key>()>
void print(const map<Key, Val, Comp>& m)
{
for(auto it = m.begin(); it != m.end(); it++)
{
pair<Key, Val> p = (pair<Key, Val>)(*it);
out2nd(p.first, p.second);
}
}
template <typename Key, typename Val, typename Comp = less<Key>()>
void print(const multimap<Key, Val, Comp>& m)
{
for(auto it = m.begin(); it != m.end(); it++)
{
pair<Key, Val> p = (pair<Key, Val>)(*it);
out2nd(p.first, p.second);
}
}
int main()
{
/*map/multimap*/
map<int, double> mp;
mp.insert(pair<int, double>(0, 61.5));
mp.insert(pair<int, double>(3, 60.5));
mp.insert(pair<int, double>(2, 68.5));
print(mp);
map<int, double, greater<int>> mpg(mp.begin(), mp.end());
print(mpg);
multimap<int, string> mmp;
mmp.insert(pair<int, string>(2, "VTY66rc"));
mmp.insert(pair<int, string>(2, "NBUTyf^%&"));
mmp.insert(pair<int, string>(1, "BBYTF^R"));
mmp.insert(pair<int, string>(3, "VTYFR^fe"));
print(mmp);
multimap<int, string, greater<int>> mmpg(mmp.begin(), mmp.end());
print(mmpg);
out(mmpg.count(2));
newline();
multimap<int, string>::iterator fd = mmpg.find(2);
pair<int, string> pfd = (pair<int, string>)(*fd);
out2nd(pfd.first, pfd.second);
fd = mmpg.lower_bound(3);
pfd = (pair<int, string>)(*fd);
out2nd(pfd.first, pfd.second);
fd = mmpg.upper_bound(3);
pfd = (pair<int, string>)(*fd);
out2nd(pfd.first, pfd.second);
pair<multimap<int, string>::iterator, multimap<int, string>::iterator> ffd = mmpg.equal_range(3);
pfd = (pair<int, string>)(*ffd.first);
out2nd(pfd.first, pfd.second);
pfd = (pair<int, string>)(*ffd.second);
out2nd(pfd.first, pfd.second);
multimap<int, string>::key_compare kcmmp = mmp.key_comp();
multimap<int, string, greater<int>>::key_compare kcmmpg = mmpg.key_comp();
out2nd(kcmmp(2, 3), kcmmpg(2, 3));
int arr[] = {4, 2, 5, 1, 3};
sort(arr, arr + sizeof(arr)/sizeof(arr[0]));
for(int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
{
out(arr[i]);
}
newline();
return 0;
}
- 特殊容器及容器配接器
#include <iostream>
#include <bitset>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <string>
using namespace std;
template <typename T> void out(const T& x){cout << x << endl;}
void print(const bitset<16>& bset)
{
for(int i = 0; i < bset.size(); i++)
{
cout << bset[i];
}
cout << endl;
}
template <typename T, typename Comp = less<T>> void print(priority_queue<T, deque<T>, Comp>& x)
{
while (!x.empty())
{
cout << x.top() << " ";
x.pop();
}
cout << endl;
}
int main()
{
/*bitset*/
bitset<16> b1;
bitset<16> b2(55);
bitset<16> b3((string)("0000001111111111111111111100000"), 2, 16);
print(b1); //0000000000000000
print(b2); //1110110000000000
print(b3); //1111111111110000
out(b1.count()); //0
out(b2.count()); //5
out(b3.count()); //12
out(b1.any()); //0 是否有1
out(b2.any()); //1
out(b3.any()); //1
out(b1.none()); //1 是否全0
out(b2.none()); //0
out(b3.none()); //0
out(b1.test(2)); //0 2是否为1
out(b2.test(2)); //1
out(b3.test(2)); //1
b1.set(5, 1);
b2.set(5, 0);
b3.set(5, 0);
print(b1); //0000010000000000
print(b2); //1110100000000000
print(b3); //1111101111110000
b1.reset(5);
b2.reset(5);
b3.reset(5);
print(b1); //0000000000000000
print(b2); //1110100000000000
print(b3); //1111101111110000
b1.flip();
b2.flip();
b3.flip();
print(b1); //1111111111111111
print(b2); //0001011111111111
print(b3); //0000010000001111
out(b1.to_ulong());
out(b2.to_ulong());
out(b3.to_ulong());
out(b1.to_string());
out(b2.to_string());
out(b3.to_string());
/*stack*/
stack<char, list<char>> st;
for(char ch = 'a'; ch <= 'g'; ch++)
{
st.push(ch);
out("Push to Stack:");
out(ch);
}
while(!st.empty())
{
out("Pop from Stack:");
out(st.top());
st.pop();
}
/*queue*/
queue<char, list<char>> qu;
for(char ch = 'a'; ch <= 'g'; ch++)
{
qu.push(ch);
out("Push to Queue:");
out(ch);
}
while(!qu.empty())
{
out("Pop from Queue:");
out(qu.front());
out(qu.back());
qu.pop();
}
/*priority_queue*/
priority_queue<int, deque<int>, less<int>> pri;
priority_queue<int, deque<int>, greater<int>> prig;
pri.push(3);
pri.push(5);
pri.push(1);
pri.push(8);
pri.push(2);
pri.push(6);
print(pri); //8 6 5 3 2 1
prig.push(3);
prig.push(5);
prig.push(1);
prig.push(8);
prig.push(2);
prig.push(6);
print(prig); //1 2 3 5 6 8
return 0;
}