您的位置:首页 > 其它

理解容器和迭代器

2015-06-09 23:46 483 查看
第12章 理解容器与迭代器

------------------------------------------------------------------------------------------------------------------------------------------------------

1、迭代器(五大类):

(1)五大类:

读迭代器(输入迭代器)

写迭代器(输出迭代器)

前向迭代器

双向迭代器

随机访问迭代器

(2)公共迭代器typedef和方法

iterator、const_iterator

reverse_iterator、const_reverse_iterator

方法: begin()、end() (半开区间)

cbegin()、cend() (const)

注:end()返回的迭代器越过了vector容器的尾部,而不是引用容器中的最后一个元素

注:只有顺序容器、关联容器和无序关联容器提供了迭代器。容器适配器和bitset类都不支持迭代元素

------------------------------------------------------------------------------------------------------------------------------------------------------

2、C++11的变化

(1)引入无序关联容器(散列表)

(2)STL容器都包含了移动构造函数和移动赋值运算符,提高了性能。例如:

原: Element myElement(12, "Twelve");

vec.push_back(myElement);

C++11: vec.push_back({12, "Twelve"}); //等价于 vec.push_back(Element(12, "Twelve"));

// Or

vec.emplace_back(12, "Twelve");

------------------------------------------------------------------------------------------------------------------------------------------------------

3、顺序容器(一):vector 容器

(1)格式: template <class T, class Allocator = allocator<T> > class vector;

----------------------------------------------------------------------------------------------------------------------------------------------

(2)创建: 1)基本创建: vector<double> doubleVector(10); // Create a vector of 10 doubles.

2)指定初始值: vector<double> doubleVector(10, 0.0); // 10 doubles of value 0.0

----------------------------------------------------------------------------------------------------------------------------------------------

(3)访问元素: operator[]运算符: 类似于数组索引,不执行边界检查

at(): 等同于operator[]运算符,但是会执行边界检查

front(): 返回第一个元素

back(): 返回最后一个元素

----------------------------------------------------------------------------------------------------------------------------------------------

(4)动态长度: vector<double> doubleVector; // Create a vector with zero elements.

1)push_back(); doubleVector.push_back(temp);

2)size(); for (size_t i = 0; i < doubleVector.size(); i++)

----------------------------------------------------------------------------------------------------------------------------------------------

(5)构造函数: 1)默认: 默认的构造函数创建一个带有0个元素的vector

如果没有提供默认值,那么新对象通过0初始化

3)初始化 initializer_list参数(C++11): vector<int> intVector({1,2,3,4,5,6});

统一初始化: vector<int> intVector = {1,2,3,4,5,6};

4)堆分配: vector<Element>* elementVector = new vector<Element>(10);

delete elementVector; //通过delete(而不是delete[])释放vector,因为vector是一个基本类型,而非数组类型

5)堆分配(使用智能指针) shared_ptr<vector<Element> > elementVector(new vector<Element>(10));

----------------------------------------------------------------------------------------------------------------------------------------------

(6)复制和赋值:1)assign(); 删除所有现有的元素,添加任意数目的新元素

2)swap(); 交换两个vector的内容

----------------------------------------------------------------------------------------------------------------------------------------------

(7)迭代器:iterator: for (vector<double>::iterator iter = doubleVector.begin();

iter != doubleVector.end(); ++iter)

{

*iter /= max;

cout << *iter << " ";

}

注:1)尽量使用前递增而不要使用后递增,更为高效。因为iter++必须返回一个新的迭代器对象,而++iter只是返回对iter的引用

2)vector迭代器是随机访问的,可以向前向后移动,而且还可以随意跳跃:--iter;

------------------------------------------------------------------------------------------------------

1)使用auto关键字 for (auto iter = doubleVector.begin();

iter != doubleVector.end(); ++iter)

{

*iter /= max;

cout << *iter << " ";

}

------------------------------------------------------------------------------------------------------

2)基于区间的for循环 for (auto& d : doubleVector)

{

d /= max;

cout << d << " ";

}

------------------------------------------------------------------------------------------------------

3)访问对象元素中的字段 vector<string> stringVector(10, "hello");

for (auto it = stringVector.begin(); it != stringVector.end(); ++it)

{

it->append(" there");

}

// 或

vector<string> stringVector(10, "hello");

for (auto& str : stringVector)

{

str.append(" there");

}

----------------------------------------------------------------------------------------------------------------------------------------------

(8)迭代器:const_iterator 注:不能通过const_iterator修改元素

cbegin()、cend() vector<string> stringVector(10, "hello");

for (auto iter = stringVector.cbegin();

iter != stringVector.cend(); ++iter)

{

cout << *iter << endl;

}

----------------------------------------------------------------------------------------------------------------------------------------------

(9)添加和删除元素

push_back()、pop_back() 追加、删除

insert() (5种形式)从任意位置插入元素

insert(const_iterator pos, const T& x); //将值x插入位置pos

insert(const_iterator pos, size_type n, const T& x); //将值x在位置pos插入n次

insert(const_iterator pos, InputIterator first, InputIterator last); //将范围first,last内的元素插入位置pos

erase() (2种形式)从任意位置删除元素

clear() 删除所有元素

----------------------------------------------------------------------------------------------------------------------------------------------

(10)大小和容量

size() 返回元素的个数

capacity() 返回在重分配之前可以保存的元素个数。因此在重分配之前还能插入的元素个数为 capacity()-size()

empty() 查询是否为空

reserve() 分配保存指定数目元素的足够空间(不会创建真正的元素,因此不要越过vector大小访问元素)

resize() 指定vector要保存的元素数目

----------------------------------------------------------------------------------------------------------------------------------------------

(11)vector<bool>特化

flip() 取反

注:除非真的需要使用动态大小的位字段,否则应该避免使用vector<bool>,而是使用bitset

------------------------------------------------------------------------------------------------------------------------------------------------------

3、顺序容器(二):list

(1)描述: 双向链表 不提供operator[]的随机访问操作,只有通过迭代器才能访问单个元素

(2)访问元素 front() 返回list的第一个元素的引用

back() 返回list的最后一个元素的引用

begin() 返回第一个元素的迭代器

end() 返回最后一个元素之后一个元素的迭代器

(3)迭代器 不能进行加减操作和其他指针运算:可以通过++iter或--iter的方式遍历,而不能使用 iter+n或iter-n等

(4)添加和删除 push_front 在首端追加

pop_front 在首端移除

注:list支持和vector一样的添加和删除元素的方法

list适用于在数据结构上执行很多插入和删除操作,但不需要基于索引快睡访问元素的应用程序

(5)大小和容量 注:支持size()、empty()、resize()

不支持reserve()、capacity()

(6)特殊list操作

splice() 插入

remove()、remove_if() 从list中删除特定元素

unique() 从list删除连续重复元素

merge() 合并灵感list

sort() 对list中的元素执行稳定排序操作

reverse() 翻转list中元素的顺序

------------------------------------------------------------------------------------------------------------------------------------------------------

4、顺序容器(三)

(1)deque 双头序列 几乎和vector是等同的,使用得少。不要求元素连续保存在内存中

(2)array(C++11) 数组 和vector类似,区别在于大小固定的,这个类的目的是让array能分配在栈上,而不是像vector总是需要访问堆

(3)forward_list(C++11) 单链表 和list类似,区别在于只支持前向迭代

------------------------------------------------------------------------------------------------------------------------------------------------------

5、容器适配器

(1)queue 队列 template <class T, class Container = deque<T> > class queue;

(2)priority_queue 优先级队列 template <class T, class Container = vector<T>,class Compare = less<T> >;

(3)stack 栈 template <class T, class Container = deque<T> > class stack;

------------------------------------------------------------------------------------------------------------------------------------------------------

5、关联容器(一)

(1)pair工具类 <utility> template <class T1, class T2> struct pair;

注:将两个可能属于不同类型的值组合起来,通过first和second公共数据成员访问这两个值

pair<string, int> myPair("hello", 5);

myOtherPair.first = "hello";

myOtherPair.second = 6;

------------------------------------------------------------------------------------------------------------------------------------------------------

6、关联容器(二):map

(1)插入元素 1)insert()

2)operator[]

(2)访问元素 1)operator[]

2)find()

3)count() 查找是否存在具有给定键的元素

(3)删除元素 1)erace()

------------------------------------------------------------------------------------------------------------------------------------------------------

7、关联容器(三):set

------------------------------------------------------------------------------------------------------------------------------------------------------

8、(C++11)无序关联容器/哈希表/散列表

------------------------------------------------------------------------------------------------------------------------------------------------------

9、其他容器:bitset

------------------------------------------------------------------------------------------------------------------------------------------------------

(done)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: