6. STL 容器
6.1 容器共同的限制和操作
复制和swap
如果要将一个容器的元素拷贝到另一个容器,并且先前的容器将不再使用,则可以用swap实现高效的拷贝,因为swap只交换容器内部数据而不影响实际存储数据。
从标准输入读入元素
Container<T> c((istream_iterator<T>(cin),
istream_iterator<T>()));
6.2 vector
删除所有的值为val的元素
vec.erase(remove(vec.begin(), vec.end(), val), vec.end());
仅删除第一个值为val的元素
vector<T>::iterator iter = find(vec.begin(), vec.end(), val);
if (iter != vec.end())
{
vec.erase(iter);
}
缩减vector的容量
vector<T>(vec).swap(vec);
6.3 deque
deque和vector一样将元素存储在动态数组中,但它是一个两端开放的容器,因此在头和尾的插入删除操作都很快。
deque占用的内存大小会自动释放,当它的元素被删除时。
6.4 list
STL中的list是一个双向链表。链表的插入和删除操作都是常数时间,同时,list还提供了容器内部和list容器之间移动元素的操作。
6.5 set和multiset
6.5.1 set的排序条件
set的排序条件必须是严格弱排序(strict weak ordering)
这就意味着:
1. 它必须是反对称的
即:若 x < y 为真,则 y < x 为假,也即:若 op(x, y) == true,则 op(y, x) == false
2. 它必须是可传递的
即:若 x < y 且y < z,则 x < z,也即:若 op(x, y) == true,op(y, z) == true,则 op(x, z) == true
3. 它必须是非自反的
即:x < x 永远为假,也即 op (x, x) === false
因此元素x,y的相等条件是 op(x, y) == false 且 op(y, x) == false;
特殊的搜索操作
lower_bond(elem) 返回第一个elem可以插入的位置,即:>= elem 的第一个元素的位置
upper_bond(elem) 返回最后一个elem可以插入的位置,即:> elem的第一个元素的位置
equal_range(elem) 则返回第一个和最后一个可以插入的位置组成的pair。
multiset仅删除第一个值为val的元素
std::multiset<T>::iterator pos = aset.find(val);
if (pos != aset.end())
{
aset.erase(pos);
}
一个运行时决定排序条件的例子:
#include <iostream>
#include <set>
using namespace std;
template<class Container>
void print(const Container& c, const char* promption)
{
cout << promption << endl;
copy(c.begin(), c.end(), ostream_iterator<Container::value_type>(cout, " "));
cout << endl;
}
template<class T>
class RuntimeCmp
{
public:
enum CmpMode {NORMAL, REVERSE};
//constructor decides the sort criterion
RuntimeCmp(const CmpMode mode_ = NORMAL)
: _mode(mode_)
{
//empty
}
//Compare the elements according to the mode
bool operator() (const T& t1_, const T& t2_)
{
return ((NORMAL == _mode) ? t1_ < t2_ : t1_ > t2_);
}
//comparision of sorting criterion
bool operator==(const RuntimeCmp& rc_)
{
return (_mode == rc_._mode);
}
private:
CmpMode _mode;
};
typedef set<int, RuntimeCmp<int> > IntSet;
void fill(IntSet& set)
{
set.insert(4);
set.insert(7);
set.insert(5);
set.insert(1);
set.insert(6);
set.insert(2);
set.insert(5);
}
int main()
{
//create a set with default sorting cirterion
IntSet set0;
fill(set0);
print(set0, "set0:");
//create a set with reverse sorting cirterion
RuntimeCmp<int> reverse_order(RuntimeCmp<int>::REVERSE);
IntSet set1(reverse_order);
fill(set1);
print(set1, "set1:");
//assign elements
set0 = set1;
set0.insert(3);
print(set0, "set0 after assignment:");
//just make sure...
if(set0.value_comp() == set1.value_comp())
{
cout << "set0 and set1 have same sorting cirterion" << endl;
}
else
{
cout << "set0 and set1 have different sorting cirterion" << endl;
}
getchar();
return 0;
}
输出
set0:
1 2 4 5 6 7
set1:
7 6 5 4 2 1
set0 after assignment:
7 6 5 4 3 2 1
set0 and set1 have same sorting cirterion
6.6 map 和 multimap
map是键值对的容器,又叫关联数组。它以键排序,它的排序条件也必须是“严格弱排序”的。
删除值为val的元素的正确方法
MapType map;
MapType::iterator pos, tmp_pos;
for (pos = map.begin(); pos != map.end(); )
{
if (pos->second == val)
{
map.erase(pos++);
}
else
{
pos++;
}
}
6.7 其他STL容器
6.7.1 STL容器String
STL的String可以看成是chars的容器,它提供了STL的容器接口,它提供了begin,end,push_back等成员函数。
6.7.2 普通数组作为STL容器
很多数组可以用于普通数组上,数组的指针可以看成是它的迭代器。
例子:
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
int coll[] = { 5, 6, 2, 4, 1, 3 };
//square all elements
transform (coll, coll+6, // first source
coll, // second source
coll, // destination
multiplies<int>()); // operation
//sort beginning with the second element
sort (coll+1, coll+6);
//print all elements
copy (coll, coll+6,
ostream_iterator<int>(cout," "));
cout << endl;
getchar();
}
输出:
25 1 4 9 16 36
6.8 引用计数实现的智能指针
一个用引用计数实现智能指针的类
#ifndef __SHARED_PTR_H__
#define __SHARED_PTR_H__
template<class T>
class SharedPtr
{
public:
explicit SharedPtr(T* p_ = 0)
:_p(p_), _count(new long(1))
{
}
SharedPtr(const SharedPtr<T>& rhs_)
:_p(rhs_._p), _count(rhs_._count)
{
++*_count;
}
~SharedPtr() throw ()
{
dispose();
}
SharedPtr& operator = (const SharedPtr<T>& rhs_)
{
if (this != &rhs_)
{
dispose();
_p = rhs_._p;
_count = rhs_._count;
++*_count;
}
return *this;
}
T* operator -> () const { return _p; }
T& operator * () const { return *_p; }
private:
void dispose() throw ()
{
if (0 == --*_count)
{
delete _p;
delete _count;
_p = 0;
_count =(long*)0;
}
}
private:
T* _p;
long* _count;
};
#endif //__SHARED_PTR_H__
6.9 何时使用何种容器
基本的指导是:
1. 一般来说,使用vector已能满足大部分的需求,它有最简单的内部数据结构,可以随机访问元素。
2. 如果你需要经常在容器头和尾插入删除元素,可以考虑使用deque,它还有个好处:能自动在删除元素的时候收缩空间。
3. 如果你需要经常在容器的中间插入和删除元素,你可以使用list,他插入和删除元素都是常数时间,无论元素在什么地方,并且由于它是基于节点的容器,它不易使迭代器失效。
4. 如果你需要一个容器的操作具有原子性,可以考虑使用list或者关联容器,但要注意某些算法会破坏这个特性。
5. 如果你需要经常在容器里根据某个条件搜索某个元素,你可以使用set或multiset。
6. hash_table 通常比二叉树实现的set或map快5到10倍,如果不依赖元素的顺序(hash_table的元素没有顺序)你可以考虑使用hash_table来提高效率。
需要字典,使用multimap。
分享到:
相关推荐
C++ Standard Template Library (STL) 是C++编程语言中不可或缺的一部分,它提供了一组高效、可重用的容器、迭代器、算法和函数对象。STL的核心思想是泛型编程,即通过模板来实现代码的复用,使得开发者可以处理不同...
《Visual C++程序设计学习笔记》是一份深入探讨VC++编程技术的综合资料,涵盖了从基础知识到实际系统开发的广泛内容。Visual C++是Microsoft公司推出的一种强大的集成开发环境,它集成了C++编译器、调试器以及MFC...
《Visual C++程序设计学习笔记》是一份深入探讨C++编程在Microsoft Visual Studio环境下的实践指南。这份笔记涵盖了从基础知识到高级技术的广泛内容,旨在帮助读者熟练掌握Visual C++的使用,提升软件开发能力。 一...
《王道C++46期学习笔记记录》是一份详细且深入的C++学习资源,旨在帮助编程初学者以及有经验的开发者进一步提升C++技能。C++是一种强大的、通用的编程语言,以其面向对象的特性、高效性能和丰富的库支持而闻名。这46...
STL(Standard Template Library,标准模板库)是C++编程语言中的一个重要组成部分,它提供了高效且灵活的数据结构和算法。这篇学习笔记将深入探讨STL的核心概念、主要组件以及其在实际编程中的应用。 首先,STL的...
《C++程序设计学习笔记》是一份深入探讨C++编程技术的资料,旨在帮助学习者掌握C++语言的核心概念和编程技巧。这份笔记基于C++程序设计特别版,集成了作者在学习过程中的精华理解和实践心得,对于初学者和有一定经验...
《C++学习笔记经典(与C比较)》这份资料应该会详细讲解这些知识点,并通过实例来帮助读者深入理解C++与C的差异,以及如何在实际编程中应用C++的特性和功能。这份资料可能会涵盖基本语法、类和对象、模板、STL的使用...
C++ Standard Template Library(STL)是C++编程语言的一个重要组件,它提供了一系列通用的数据结构和算法模板,使程序员能够以一种标准化和高效的方式处理数据。STL的主要组成部分包括容器(containers)、迭代器...
- **STL(Standard Template Library)**:深入理解容器、迭代器、算法的使用,以及自定义比较函数和迭代器适配器。 在学习过程中,不断实践和编写代码是巩固知识的关键。通过编写小程序、解决实际问题来加深对C++...
《达内学生C++学习笔记》是一份专为初学者设计的C++教程,旨在提供清晰易懂、逐步深入的学习路径。这份笔记涵盖了C++语言的基础到进阶内容,是学习C++的理想辅助资料。 首先,C++是一种静态类型的、编译式的、通用...
本篇学习笔记主要涵盖了前三章的内容,重点关注STL(Standard Template Library,标准模板库)中的容器、特别是vector的使用,以及迭代器的概念。接下来我们将详细探讨这些知识点。 首先,STL是一个强大的工具集,...
《C++学习笔记》是一部非常实用的资源,适合那些对C++编程语言有着浓厚兴趣或者正在学习C++的初学者。这份笔记详细介绍了C++语言的基础知识、核心概念以及高级特性,旨在帮助读者掌握C++编程的核心技能。 C++是...
5. **STL(Standard Template Library)**:STL是C++的标准库,包含容器(如vector、list、set等)、迭代器、算法和函数对象,为程序员提供了高效的数据结构和算法。 6. **异常处理**:C++提供了异常处理机制,通过...
10. **STL(Standard Template Library)**:STL是一组通用的C++模板类和函数,包括容器、迭代器、算法和函数对象,它极大地提高了代码的效率和可读性。 11. **I/O流**:C++的I/O流库使得输入输出操作更加直观和...
C++ SLS(Standard Library Style Guidelines)是一组用于编写C++标准库的编码规范,旨在提供高质量、统一的代码风格。这些指南对于任何参与C++编程,尤其是进行课程设计或大型项目开发的人来说都是极其重要的。以下...
本学习笔记将深入探讨C++的基础、核心概念以及高级特性,帮助读者从初学者到熟练掌握C++。 一、C++基础 C++的基础包括基本语法、数据类型、变量、运算符、流程控制(如if语句、switch语句、for循环、while循环)和...
这个“C & C++学习笔记集合”显然是一份综合性的资源,旨在帮助学习者深入理解和掌握这两种语言。 C 语言是基础,它的语法简洁明了,对内存管理有直接的控制,是理解计算机底层工作原理的良好起点。C 语言的核心...
6. **STL(Standard Template Library)标准库**:C++的STL包含容器(如vector、list、set等)、迭代器、算法和函数对象。熟练使用STL可以提高代码效率,简化编程任务。 7. **异常处理**:C++的异常处理机制允许...
12. **STL(Standard Template Library)**:STL是C++标准库的一部分,包含了容器(如vector、list、map等)、算法和迭代器,极大地提高了编程效率。 学习C-C++的基础,不仅需要理解和掌握上述知识点,还需要通过...
2. **类模板**:类模板可以生成处理不同类型数据的类,提供了泛型数据结构和算法,如STL(Standard Template Library)中的容器(vector、list、set等)和算法(sort、find等)。 【异常处理】 C++提供了一种处理...