STL阶段性总结

STL概述
.

  1. STL是C++标准程序库的核心,深刻影响了标准程序库的整体结构
  2. STL由一些可适应不同需求的集合类(collection class),以及在这些数据集合上操作的算法(algorithm)构成
  3. STL内的所有组件都由模板(template)构成,其元素可以是任意类型
  4. STL是所有C++编译器和所有操作系统平台都支持的一种库

STL组件

  1. 容器(Container) - 管理某类对象的集合
  2. 迭代器(Iterator) - 在对象集合上进行遍历
  3. 算法(Algorithm) - 处理集合内的元素
  4. 容器适配器(container adaptor )
  5. 函数对象(functor)

STL容器的共同能力
所有容器中存放的都是值而非引用。如果希望存放的不是副本,容器元素只能是指针。
所有元素都形成一个次序(order),可以按相同的次序一次或多次遍历每个元素

STL容器元素的条件

  1. 必须能够通过拷贝构造函数进行复制
  2. 必须可以通过赋值运算符完成赋值操作
  3. 必须可以通过析构函数完称销毁动作
  4. 序列式容器元素的默认构造函数必须可用
  5. 某些动作必须定义operator ==,例如搜寻操作
  6. 关联式容器必须定义出排序准则,默认情况是重载operator <

初始化(initialization)

  1. 产生一个空容器
std::list<int> l;
  1. 以另一个容器元素为初值完成初始化
std::list<int> l;
…
std::vector<float> c(l.begin(),l.end());
  1. 以数组元素为初值完成初始化
int array[]={2,4,6,1345};
…
std::set<int> c(array,array+sizeof(array)/sizeof(array[0]));

与大小相关的操作(size operator)

  1. size()-返回当前容器的元素数量
  2. empty()-判断容器是否为空
  3. max_size()-返回容器能容纳的最大元素数量

比较(comparison)
==,!=,<,<=,>,>=

  1. 比较操作两端的容器必须属于同一类型
  2. 如果两个容器内的所有元素按序相等,那么这两个容器相等
  3. 采用字典式顺序判断某个容器是否小于另一个容器

赋值(assignment)和交换(swap)

  1. swap用于提高赋值操作效率

与迭代器(iterator)相关的操作

  1. begin()-返回一个迭代器,指向第一个元素
  2. end()-返回一个迭代器,指向最后一个元素之后
  3. rbegin()-返回一个逆向迭代器,指向逆向遍历的第一个元素
  4. rend()-返回一个逆向迭代器,指向逆向遍历的最后一个元素之后

元素操作

  1. insert(pos,e)-将元素e的拷贝安插于迭代器pos所指的位置

  2. erase(beg,end)-移除[beg,end]区间内的所有元素

  3. clear()-移除所有元素

迭代器(iterator)
所有容器都提供两种迭代器

  1. container::iterator以“读/写”模式遍历元素
  2. container::const_iterator以“只读”模式遍历元素

双向迭代器
可以双向行进,以递增运算前进或以递减运算后退、可以用==和!=比较。
list、set和map提供双向迭代器

list<int> l; 
for(pos=l.begin();pos!=l.end();++pos{}

随机存取迭代器
除了具备双向迭代器的所有属性,还具备随机访问能力。
可以对迭代器增加或减少一个偏移量、处理迭代器之间的距离或者使用<和>之类的关系运算符比较两个迭代器。

vector、deque和string提供随机存取迭代器
vector<int> v; 
for(pos=v.begin();pos<v.end();++pos{}

vector

  1. vector模拟动态数组
  2. vector的元素可以是任意类型T,但必须具备赋值和拷贝能力(具有public拷贝构造函数和重载的赋值操作符)
  3. 必须包含的头文件#include
  4. vector支持随机存取

vector的大小(size)和容量(capacity)

  1. size返回实际元素个数,
  2. capacity返回vector能容纳的元素最大数量。如果插入元素时,元素个数超过capacity,需要重新配置内部存储器。

vector 构造、拷贝和析构

  1. vector c 产生空的vector

  2. vector c1(c2) 产生同类型的c1,并将复制c2的所有元素

  3. vector c(n) 利用类型T的默认构造函数和拷贝构造函数生成一个大小为n的vector

  4. vector c(n,e) 产生一个大小为n的vector,每个元素都是e

  5. vector c(beg,end) 产生一个vector,以区间[beg,end]为元素初值

  6. ~vector() 销毁所有元素并释放内存。

  7. c.capacity() 返回重新分配空间前可容纳的最大元素数量

  8. c.reserve(n) 扩大容量为n

vector赋值操作

  1. c.assign(n,e) 将元素e的n个拷贝赋值给c
  2. swap(c1,c2) 全局函数将c1和c2元素互换
std::list<T> l;
 std::vector<T> v;
 …
 v.assign(l.begin(),l.end());

vector元素存取

  1. at(idx) 返回索引idx所标识的元素的引用,进行越界检查
  2. operator 返回索引idx所标识的元素的引用,不进行越界检查
 std::vector<T> v;//empty

 v[5]= t;			//runtime error
 std::cout << v.front();	//runtime error

vector迭代器相关函数

  • begin()返回一个迭代器,指向第一个元素
  • end()返回一个迭代器,指向最后一个元素之后
  • rbegin() 返回一个逆向迭代器,指向逆向遍历的第一个元素
  • rend() 返回一个逆向迭代器,指向逆向遍历的最后一个元素

vector安插(insert)元素

  • c.insert(pos,e) 在pos位置插入元素e的副本,并返回新元素位置
  • c.insert(pos,n,e) 在pos位置插入n个元素e的副本
  • c.insert(pos,beg,end) 在pos位置插入区间[beg,end]内所有元素的副本
  • c.push_back(e) 在尾部添加一个元素e的副本

vector移除(remove)元素

  • c.pop_back() 移除最后一个元素但不返回最后一个元素
  • c.erase(pos) 删除pos位置的元素,返回下一个元素的位置
  • c.erase(beg,end) 删除区间[beg,end]内所有元素,返回下一个元素的位置
  • c.resize(num) 将元素数量改为num(增加的元素用defalut构造函数产生,多余的元素被删除
  • c.resize(num,e)将元素数量改为num(增加的元素是e的副本)
  • c.clear() 移除所有元素,清空容器
#include <iostream>
int main(){
    vector<int> a;
    for (int i = 0; i < 5; ++i){
        a.push_back(5 - i);
    }
    cout << a.size() << endl;
    a.pop_back();
    a[0] = 1;
    cout << a.size() << endl;
    for (int i = 0; i < (int)a.size(); ++i){
        cout << a[i] << ", " << endl;
    }    cout << endl;
    sort(a.begin(), a.end());
    cout << "Size: " << a.size() << endl;
    for (int i = 0; i < (int)a.size(); ++i){
        cout << a[i] << ", " << endl;
    }
    cout << endl;

    a.clear();
    cout << "Size: " << a.size() << endl;
    return 0;
}

map/multimap

  • 使用平衡二叉树管理元素
  • 元素包含两部分(key,value),key和value可以是任意类型
  • 必须包含的头文件#include
  • 根据元素的key自动对元素排序,因此根据元素的key进行定位很快,但根据元素的value定位很慢
  • 不能直接改变元素的key,可以通过operator []直接存取元素值
  • map中不允许key相同的元素,multimap允许key相同的元素

map/multimap构造、拷贝和析构

  • map c 产生空的map
  • map c(op)以op为排序准则产生一个空的map
  • map c(beg,end)以区间[beg,end]内的元素产生一个map
  • map c(beg,end,op)
  • 以op为排序准则,以区间[beg,end]内的元素产生一个map
  • c.size()返回元素个数
  • c.empty() 产生同类型的c1,并复制c2的所有元素
  • map c(op) 以op为排序准则产生一个空的map
  • map c(beg,end)以区间[beg,end]内的元素产生一个map
  • map c(beg,end,op) 以op为排序准则,以区间[beg,end]内的元素产生一个map

map/multimap 赋值

  • c1 = c2 将c2的全部元素赋值给c1
  • c1.swap(c2) 将c1和c2的元素互换
  • swap(c1,c2) 将c1和c2的元素互换
  • map/multimap 特殊搜寻操作
  • count(key) 返回”键值等于key”的元素个数
  • find(key) 返回”键值等于key”的第一个元素,找不到返回end
  • lower_bound(key) 返回”键值大于等于key”的第一个元素
  • upper_bound(key)返回”键值大于key”的第一个元素
  • equal_range(key) 返回”键值等于key”的元素区间

map/multimap 迭代器相关函数

  • begin() 返回一个双向迭代器,指向第一个元素
  • rbegin() 返回一个逆向迭代器,指向逆向遍历的第一个元素
  • rend()返回一个逆向迭代器,指向逆向遍历的最后一个元素

map/multimap 安插(insert)元素

  • c.insert(pos,e) 在pos位置为起点插入e的副本,并返回新元素位置(插入速度取决于pos)

  • c.insert(e) 插入e的副本,并返回新元素位置

  • c.insert(beg,end) 将区间[beg,end]内所有元素的副本插入到c中

map/multimap移除(remove)元素

  • c.erase(pos)删除迭代器pos所指位置的元素,无返回值
  • c.erase(val)移除所有值为val的元素,返回移除元素个数
  • c.erase(beg,end) 删除区间[beg,end]内所有元素,无返回值
  • c.clear() 移除所有元素,清空容器

map/multimap map应用实例:map
multimap应用实例:multimap

1.

struct T1{
    int v;
    bool operator<(const T1 &a)const{
        return (v < a.v);
    }
};

struct T2{
    int v;
};
struct cmp{
    const bool operator()(const T2 &a, const T2 &b){
        return (a.v < b.v);
    }
};
struct cmp{
    const bool operator()(const T2 &a, const T2 &b){
        return (a.v < b.v);
    }
};

int main(){
    map<T1, int>mt1; //example for user-defined class
    map<T2, int, cmp>mt2; //example for user-defined class(functor)

    map<string, int> m2;
    map<string, int>::iterator m2i, p1, p2;
    //map<string, int, greater<string> >m2;
    //map<string, int, greater<string> >::iterator m2i, p1, p2;
   
    m2["abd"] = 2;
    m2["abc"] = 1;
    m2["cba"] = 2;
    m2.insert(make_pair("aaa", 9));
    m2["abf"] = 4;
    m2["abe"] = 2;
    cout << m2["abc"] << endl;
    m2i = m2.find("cba");
    if(m2i != m2.end()){
        cout << m2i->first << ": " << m2i->second << endl;
    }else{
        cout << "find nothing" << endl;
    }
    cout << "Iterate" << endl;
    for(m2i = m2.begin(); m2i != m2.end(); m2i++){
        cout << m2i->first << ": " << m2i->second << endl;
    }
}
int main(){
    multimap<string, int> mm1;
    multimap<string, int>::iterator mm1i, p1, p2;
    mm1.insert(make_pair("b", 3));
    mm1.insert(make_pair("a", 0));
    mm1.insert(make_pair("b", 5));
    mm1.insert(make_pair("c", 4));
    mm1.insert(make_pair("b", 2));
    cout << mm1.size() << endl;
    for(mm1i = mm1.begin(); mm1i != mm1.end(); mm1i++){
        cout << mm1i->first << ": " << mm1i->second << endl;
    }
    cout << "COUNT: " << mm1.count("b") << endl;
    cout << "Bound: " << endl;
    p1 = mm1.lower_bound("b");
    p2 = mm1.upper_bound("b");
    for(mm1i = p1; mm1i != p2; mm1i++){
        cout << mm1i->first << ": " << mm1i->second << endl;
    }

    return 0;
}
#include <set>
#include <iostream>
using namespace std;
main()  {
	typedef set<double,less<double> > double_set;
	const int SIZE = 5;
	double a[SIZE] = {2.1,4.2,9.5,2.1,3.7 };
	double_set doubleSet(a,a+SIZE);
	ostream_iterator<double> output(cout," ");
	cout << "1) ";
	copy(doubleSet.begin(),doubleSet.end(),output);
	cout << endl;
	pair<double_set::const_iterator, bool> p;
	p = doubleSet.insert(9.5); 
	if( p.second ) 
		cout << "2) " << * (p.first)  << " inserted" << endl;
	else
		cout << "2) " << * (p.first)  << " not inserted" << endl;
}
//insert函数返回值是一个pair对象, 其first是被插入元素的迭代器,second代表是否成功插入了

输出:

  1. 2.1 3.7 4.2 9.5
  2. 9.5 not inserted
#include <iostream>
#include <map>
using namespace std;

ostream & operator <<( ostream & o,const pair<  int,double> & p)
{
	o << "(" << p.first  << "," << p.second << ")";
	return o;
}
int main()  {
	typedef map<int,double,less<int> > mmid;
	mmid pairs;
	cout << "1) " << pairs.count(15) << endl;
	pairs.insert(mmid::value_type(15,2.7));
	pairs.insert(make_pair(15,99.3)); //make_pair生成一个pair对象
	cout << "2) " << pairs.count(15) << endl;
	pairs.insert(mmid::value_type(20,9.3));
	mmid::iterator i;
	cout << "3) ";
	for( i = pairs.begin(); i != pairs.end();i ++ )
		cout << * i  << ",";

输出:

  1. 0
  2. 1
  3. (15,2.7),(20,9.3),
  4. (15,2.7),(20,9.3),(40,0),
  5. (15,6.28),(20,9.3),(40,0),

count:

  • size_t count(InIt first, InIt last, const T& val);
  • 计算[first,last)
    中等于val的元素个数

count_if

  • size_t count_if(InIt first, InIt last, Pred pr);

    计算[first,last) 中符合pr(e) == true 的元素 e的个数

for_each

  • template<class InIt, class Fun>
    Fun for_each(InIt first, InIt last,Fun f);
    对[first,last)中的每个元素 e ,执行 f(e) , 要求 f(e)不能改变e
#include <vector>
#include <iostream>
#include <numeric>
#include <list>
#include <algorithm>
using namespace std;
class CLessThen9  {
public:
	bool operator()( int n) { return n < 9; }
};
void outputSquare(int value ) {  cout << value * value << " "; }
}
main() {
	const int SIZE = 10;
	 
	int a1[] = { 100,2,8,1,50,3,8,9,10,2 };
	vector<int> v(a1,a1+SIZE);
	ostream_iterator<int> output(cout," ");
	cout << endl << "2)";
	cout << count(v.begin(),v.end(),8);
	cout << endl << "3)";
	cout << count_if(v.begin(),v.end(),CLessThen9());

排序和查找算法
find

  • template<class InIt, class T>
    InIt find(InIt first, InIt last, constT& val);
  • 返回区间 [first,last) 中的迭代器 i ,使得 * i == val

find_if
template<class InIt, class Pred>
InIt find_if(InIt first, InIt last, Pred pr);
返回区间 [first,last) 中的迭代器 i, 使得 pr(*i) == true

#include <vector>
#include <bitset>
#include <iostream>
#include <numeric>
#include <list>
#include <algorithm>
using namespace std;
bool Greater10(int n)
{
	return n > 10;
}
main()  {
	const int SIZE = 10;
	int a1[] = { 2,8,1,50,3,100,8,9,10,2 };
	vector<int> v(a1,a1+SIZE);
	ostream_iterator<int> output(cout," ");
	vector<int>::iterator location;
	location = find(v.begin(),v.end(),10);
	if( location != v.end()) {
		cout << endl << "1) " << location - v.begin();
	}
	location = find_if( v.begin(),v.end(),Greater10);
	if( location != v.end())
		cout << endl << "2) " << location - v.begin();
输出:
1) 8
2) 3

sort 快速排序

  • template void sort(RanIt first, RanIt last);
    按升序排序。判断x是否应比y靠前,就看 x < y 是否为true
  • template<class RanIt, class Pred> void sort(RanIt first, RanIt last,Pred pr);
    按升序排序。判断x是否应比y靠前,就看 pr(x,y) 是否为true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值