《STL Tutorial Reference》 Chapt 6 Containers
2007-10-30 17:26
190 查看
Chapt 6 STL Containers
Content included:How to use, internal data structures, operations, and the performance: general abilities, advantages, and disadvantages of all container types.
Sepecial classes: container adapters(: stack, queue, priority queue), bitmaps, and valarrays.
6.1 通用容器能力与操作
每个容器都具备的能力:所有容器提供值而非引用语义。当插入时,容器内部拷贝元素而非管理它们的引用。因此,STL容器存储和的元素必须能拷贝,即需要public copy constructor
通常,所有的元素都有其次序。
通常,操作并非安全。调用者必须确保操作的参数满足要求。使用STL不会抛出异常。
通用操作:
初始化:每个容器类提供一个default constructor, copy constructor, destructor, 以及用另一个容器元素、数组、标准输入来初始化的constructor.
ConType c | |
ConType c1(c2) | |
ConType c(beg, end) | |
c.~ConType() | |
c.size() | |
c.empty() | |
c.max_size() | |
c1 == c2 | |
c1 != c2 | |
c1 < c2 | |
c1 > c2 | |
c1 <= c2 | |
c1 >= c2 | |
c1 = c2 | assign operator |
c1.swap(c2) | member function |
swap(c1, c2) | global function |
c.begin() | |
c.end() | |
c.rbegin | return reverse iterator for 1st element |
c.rend() | |
c.insert(pos, elem) | |
c.erase(beg, end) | remove elements in range [beg, end) |
c.clear() | remove all |
c.get_allocator() |
数组初始化:
int array[] = {2, 3, 17} ..//std:set<int> c(array, array+sizeof(array)/sizeof(array[0]);
标准输入初始化:
std:deque<int> c((std::istream_iterator<int>(std::cin)), std::istream_iterator<int>());
6.2 Vector
模型:动态数组提供随机访问。
容量:
capacity() 返回不重新分配内存的情况下最大可能的元素个数
max_size() 返回可以容纳的最大大小
这两个函数都是依赖于STL实现的
保留一定容量的以避免重新分配内存带来的耗时:
方式一:
std::vector<int> v;
v.reverve(80); //reverve memory for 80 elements
方式二:
std::vector<int> v(5);
//creates a vector and initializes it with five values, call 5 times the default constructor of type T
推荐第一种方式
元素访问:
c.at(idx) | return element in idx with range checking |
c[idx] | return element in idx with no range checking |
c.front() | return 1st element(no check 1st element exists) |
c.back() | return last element(no check last element exists) |
下面代码:
std::vector<Elem> coll; //empty vector
coll[5] = elem;//RUNTIME ERROR? undefine behavior
std::cout << coll.front();RUNTIME ERROR? undefine behavior
迭代器函数:
c.begin() |
c.end() |
c.rbegin() |
c.rend() |
c.insert(pos, elem) | |
c.insert(pos, n, elem) | |
c.insert(pos, beg, end) | |
c.push_back(elem) | |
c.pop_back() | |
c.erase(pos) | |
c.erase(beg,end) | |
c.resize(num) | |
c.resize(num, elem) | |
c.clear() |
class vector<bool>
比通常是实现更节省空间,每个元素至少保留1bit
这样导致模板操作可能不适合vector<bool>
6.3 Deques
也是使用动态数组管理元素deque典型的实现是用一束单个的block,第一block以一个方向增长,最后一个block以相反方向增长
和vector比较,操作只有2个不同:
deque没有提供capacity()和reverve()函数
deque提供了push_front()和pop_front()函数
6.4 List
插入和移除元素:
c.insert(pos, elem) | |
c.insert(pos, n, elem) | |
c.insert(pos, beg, end) | |
c.push_back(elem) | |
c.pop_back() | |
c.push_front(elem) | |
c.pop_back() | |
c.remove(val) | |
c.remove_if(op) | |
c.erase(pos) | |
c.erase(beg, end) | |
c.resize(num) | |
c.resize(num, elem) | |
c.clear() |
移接函数 (Splice Functions)
c.unique() | 移除重复元素 |
c.unique(op) | |
c1.splice(pos,c2) | c2的所有元素移到c1的pos前 |
c1.splice(pos, c2, c2beg, c2end) | c2的[c2beg, c2end)范围内的元素移到c1的pos前 |
c.sort() | 按升序排序 |
c1.sort(op) | |
c1.merge(c2) | 合并2个有序list c1和c2 |
c1.merge(c2, op) | |
c.reverse() | 反转 |
6.5 Sets 和 Multisets
set通常实现为平衡二叉树(Balanced Binary Trees)实际上,set和multiset典型的实现为红黑树(Red-black Trees)
自动排序的最大优点是搜索某个值时有很好的表现。
但是也有很大的限制,你不能直接改变元素的值,因为这可能会破坏正确的次序。因此要修改一个元素的值,你必须先移除拥有旧值的元素,然后插入一个拥有新值的元素。
set和multiset不提供直接元素访问的操作
通过iterator的间接访问有限制:从iterator的观点看,元素的值是constant
set<Type> c | set<Type, op> c |
set<Type> c(op) | set<Type, op> c(op) |
set<Type> c1(c2) | set<Type, op> c1(c2) |
set<Type> c(beg, end) | set<Type, op> c(beg, end) |
set<Type> c(beg, end, op) | set<Type, op> c(beg, end, op) |
c.~set<Type>() | c.~set<Type, op>() |
count(elem) | |
find(elem) | |
lower_bound(elem) | 返回>=elem的位置 |
upper_bound(elem) | 返回>elem的位置 |
equal_range(elem) | |
#include <iostream>
[code]#include <set>
using namespace std;
int main ()
{
set<int> c;
c.insert(1);
c.insert(2);
c.insert(4);
c.insert(5);
c.insert(6);
cout << "lower_bound(3): " << *c.lower_bound(3) << endl;
cout << "upper_bound(3): " << *c.upper_bound(3) << endl;
cout << "equal_range(3): " << *c.equal_range(3).first << " "
<< *c.equal_range(3).second << endl;
cout << endl; cout << "lower_bound(5): " << *c.lower_bound(5) << endl;
cout << "upper_bound(5): " << *c.upper_bound(5) << endl;
cout << "equal_range(5): " << *c.equal_range(5).first << " "
<< *c.equal_range(5).second << endl; system("PAUSE");
return 0;
}
[/code]
插入和移除操作:
c.insert(elem) | |
c.insert(pos, elem) | |
c.insert(beg, end) | |
c.erase(elem) | |
c.erase(elem) | |
c.erase(pos) | |
c.erase(beg, end) | |
c.clear() |
set
pair<iterator, bool> insert(const value_type &elem);
iterator insert(iterator pos_hint, const value_type& elem);
multiset
iterator insert(const value_type& elem);
iterator insert(iteratir pos_hint, const value_type& elem);
set不提供remove()函数,而提供erase函数。
序列容器提供的erase()函数
iterator erase(iterator pos);
iterator erase(iterator beg, iterator end);
关联容器提供的erase()函数
void erase(iterator pos)
void erase(iterator beg, iterator end)
6.6 Map和Multimap
和set一样,通常map也是以平衡二叉树作为实现。
可以将set看作特殊的map:其key和value是相同的。
一点差别是:1)map的元素是key/value对 2)map可以作为关联数组
std::map<std::string,float> coll; // empty collection
/*insert "otto"/7.7 as key/value pair
*-first it inserts "otto"/float()
*-then it assigns 7.7
*/
coll["otto"] = 7.7;
总结:何时该使用何种容器?参考下表
默认情况下,你应该使用vector.它有最简单的内部数据结构并提供了随机访问。这样,数据访问是方便且灵活,并且数据处理也是足够快
如果你经常在序列开始和结尾插入/删除元素,你应该使用deque.另外,如果这是重要的:当元素移除时,由容器使用的内部存储量减少时,你也应使用deque。再者,因为vector通常使用一个block,而deque可能包含更多的元素,因为它使用多个block
如果你插入、移除或移动元素经常发生在容器中间,考虑使用list。list提供特殊的成员函数以常数时间来从一个容器移动元素到另一个。但是注意,因为List没有提供随机访问,当你只拥有list的起始,在访问元素时你可能遇到困难
像所有的node-based容器,list没有使指向元素的iterator无效,只要这些元素是容器的一部分。vector使得所有超出容量的iterator、指针、引用无效。deque当改变它们的size,也使相应的iterator、指针、引用无效。
如果你需要一个能handle exception的容器:每个操作或者成功或者无效,你应使用list或者关联容器。
如果你通常需要依据搜索准则搜索元素,使用set或multiset.
在搜索1000个元素时,O(Logn)理论上比O(n)快10倍,hash表通常比二叉树快5~10倍。如果hash容器可取得,你可以考虑使用
如果为了处理key/value对,使用map或multimap(或hash)
如果你需要一个字典,使用multimap
6.10 容器类内部定义细节:
6.10.1 Type Definitions
container::value_type元素类型
vector: typedef _Tp value_type;
set/multiset:(记住这个value_type是const)
typedef _Key key_type;
typedef _Key value_type;
map/multimap:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef pair<const _Key,_Tp> value_type;
vector,deque,list,set/multiset,map/multimap,string提供
container::reference
容器元素的引用
典型情况下为: container::value_type&
vector,deque,list,set/multiset,map/multimap,string提供
container::const_reference
容器const元素的引用
典型情况下为: cosnt container::value_type&
vector,deque,list,set/multiset,map/multimap,string提供
container::iterator
iterator类型
vector,deque,list,set/multiset,map/multimap,string提供
container::const_iterator
constant iterators类型.
vector,deque,list,set/multiset,map/multimap,string提供
container::reverse_iterator
reverse iterators类型.
vector,deque,list,set/multiset,map/multimap提供
container::const_reverse_iterator
constant reverse iterators类型.
vector,deque,list,set/multiset,map/multimap,string提供
container::size_type
unsigned int类型 for size values.
vector,deque,list,set/multiset,map/multimap,string提供
container::difference_type
signed int类型 for difference values.
vector,deque,list,set/multiset,map/multimap,string提供
container::key_type
For sets and multisets, it is equivalent to value_type.
set/multisets, map/multimap提供.
container::mapped_type
The type of the value of the elements of associative containers.
map/multimap提供.
container::key_compare
The type of the comparison criterion of associative containers.
set/multiset, map/multimap提供.
container::value_compare
The type of the comparison criterion for the whole element type. For sets and multisets, it is equivalent to key_compare. For maps and multimaps, it is an auxiliary class for a comparison criterion that compares
only the key part of two elements. Provided by sets, multisets, maps, and multimaps.
container::allocator_type
The type of the allocator.
vector,deque,list,set/multiset,map/multimap,string提供
6.10.2 Construct, Copy, Destruct 操作
container::container()explicit container::container(const CompFunc& op)
explicit container::container(const container& c)
explicit container::container(size_type num)
container::container(size_type num, const T& value)
container::container(InputIterator beg, InputIterator end)
container::container(InputIterator beg, InputIterator end, const ComFunc& op)
container::~container()
6.10.3 非修改操作
size操作size_type container::size() const
bool container::empty() const
size_type container::max_size() const
以上vector,deque,list,set/multiset,map/multimap,string都提供
capacity操作
container::capacity() const
vector,string提供
container::reserve() const
vector,sting提供
比较操作
bool operator ==(const container& c1, const container& c2)
bool operator !=(const container& c1, const container& c2)
bool operator > (const container& c1, const container& c2)
bool operator < (const container& c1, const container& c2)
bool operator >=(const container& c1, const container& c2)
bool operator <=(const container& c1, const container& c2)
两个容器有相同数目的元素,并且按次序相等,返回true
关联容器的特殊非修改操作
size_type container::count(const T& value) const
线性复杂度
iterator container::find(const T& value)
const_iterator container::find(const T& value) const
find()算法的特殊版本
log复杂度
iterator container::lower_bound(const T& value)
const_iterator container::lower_bound(const T& value)
iterator container::upper_bound(const T& value)
const_iterator container::upper_bound(const T& value)
log复杂度
pair<iterator, iterator>container::equal_range(const T& value)
pair<const_iterator, const_iterator>container::equal_range(const T& value) const
6.10.4 assignment操作
container& container::operator=(const container& c)void container::assign(size_type num, const T& value)
将容器所有元素清空,并指派num个元素,值都为value
void container::assign(InputIterator beg, InputIterator end)
以上两个assign函数只有vector,deque,list,string提供
void container::swap(container& c)
void swap(container& c1, container& c2)
6.10.5 直接访问操作
reference container::at(size_type idx)const_reference container::at(size_type idx) const
reference container::operator [](size_type idx)
const_reference container::operator [](size_type idx) const
T& map::operator[](const key_type& key)
此即关联数组,只有map提供
reference container::front()
const_reference container::front()
vector, deque, list提供
reference container::back()
const_reference container::back()
vector, deque, list提供
6.10.6 生成iterator的操作
iterator container::begin()
const_iterator container:: begin () const
iterator container::end()
const_iterator container::end() const
reverse_iterator container::rbegin()
const_reverse_iterator container::rbegin() const
reverse_iterator container::rend()
const_reverse_iterator container::rend() const
以上所有容器都提供
6.10.7 Insert / Remove 操作
insert:
iterator container::insert(const T& value)set, map提供
pair<iterator,bool> container::insert(const T& value)
multiset, multimap提供
iterator container::insert(iterator pos, const T& value)
所有容器都提供
void container::insert(iterator pos, size_type num, const T& value)
仅顺序容器提供
void container::insert(InputIterator beg, InputIterator end)
仅关联容器提供
void container::insert(iterator pos, InputIterator beg, InputIterator end)
仅顺序容器提供
void container::push_front(const T& value)
void container::pop_front()
仅deque,list提供
void container::push_back(const T& value)
void container::pop_back()
vector, deque, list,string提供
remove:
void list::remove(const T& value)void list::remove_if(UnaryPredicate op)
仅list提供
删除所有list中值等于value的元素
顺序容器中唯一提供以值的方式删除的容器,其他顺序容器要以值方式删除,必须使用find()算法得到iterator
erase:
size_type container::erase (const T& value)关联容器提供
void container::erase(iterator pos)
void container::erase(iterator beg, iterator end)
关联容器提供
iterator container::erase(iterator pos)
iterator container::erase(iterator beg, iterator end)
顺序容器提供
resize:
void container::resize(size_type num)void container::resize(size_type num, T value)
顺序容器提供..这个比较特别,可能引起iterator无效
clear:
void container::clear()所有容器都提供
6.10.8 List的特殊成员函数
void list::unique()
void list::unique(BinaryPredicate op)
void list::splice(iterator pos, list& source)
void list::splice(iterator pos, list& source, iterator sourcePos)
void list::splice(iterator pos, list& source, iterator sourceBeg, iterator sourceEnd)
void list::sort()
void list::sort(CompFunc op)
void list::merge(list& source)
void list::merge(list& source, CompFunc op)
标准要求两list是已排序的,但是你也可以使用2未排序的list
未测试过有何区别(((!!!
void list::reverse ()
6.10.9 Allocator支持
待续..
6.11.9 Exception handle
相关文章推荐
- 《STL Tutorial Reference》Chapt 4 Utility
- 《STL Tutorial Reference》Chapt 5 STL overview
- 《STL Tutorial Reference》 Chapt 7 Iterators
- STL之containers和<algorithm>-Reference
- STL Tutorial Reference 读后总结
- STL Tutorial and Reference Guide -- summary
- STL Tutorial and Reference Guide -- summary
- MathJax basic tutorial and quick reference(LaTex数学公式语法)
- SOES(EtherCAT中的sercos over EtherCAT)v1.0.0——tutorial.txt File Reference
- MathJax basic tutorial and quick reference
- You may experience an access violation when you access an STL object through a pointer or reference in a different DLL or EXE
- 【STL记录】Containers--Deques
- 【STL】【RBTree为啥带3个参数(T,Reference,Pointer)】
- C++STL::两种方式实现STL容器的reference语义
- OpenGL(R) SuperBible: Comprehensive Tutorial and Reference (4th Edition)
- An Introductory STL tutorial
- 一劳永逸搭建android开发环境(android官网reference sample api tutorial全下载)
- Spring 3 MVC: Themes In Spring-Tutorial With Example---reference
- Android NDK r6b使用stl遇到undefined reference to `std::__node_alloc::_M_allocate(unsigned int&)” 的终极解决办法
- 【STL记录】Containers--Vectors