Prefer C++ (二)

4、超强的标准库

 

标准库里有什么呢,同C标准库最大的不同应该是STL。有了STL,不必再写大多的标准数据结构和算法,并且可获得非常高的性能。

Stl中有几个基本的概念:

容器:可容纳各种数据类型的数据结构。

迭代器:可依次存取容器中数据的结构

算法:通过迭代器对容器进行某种操作的函数

举个容易理解的例子:

数组就是个容器,而指针就是迭代器。

 

接下来将用几小节专门描述stl的概貌。

 

下面所提到的内容多取自《C++ 标准程序库》一书,以下将不另行说明。

4.1 stl中的容器

 

标准容器有7种,不同实现有相应的扩充。

7种容器对应的模型如下:

 

vector

 

其中箭头表示数据增长方向。实际上就是个动态数组。在尾端增删元素具有较佳的性能。

 

Deque

 

在两端增删元素具有较佳的性能。

 


 

List 

双向链表,在任何位置增删元素都具有相近的性能。

上述三种容器称为序列式容器(sequence container)。元素的插入位置同元素的值无关。

 

 


 

Set/Multiset:

 

 

 

 

此种容器内的元素是已序的,插入任何元素,都按相应的排序准则来确定其位置。

Set中不允许相同元素,multiset中允许存在相同的元素。

 

Map/Multimap:

 

 

 

 

 

Map同Multimap的不同在于是否允许相同的元素。

Map与Set的不同在于Map中存放的是成对的key/value。

并根据key对元素进行排序。

 

上述四种容器称为关联式容器(Associative Container)。特点是在查找时具有非常好的性能。

以上述7种容器为基础,stl还实现了Stacks,Queues,Priority Queues。

Map来举个例子:

typedef map<string,float> mapforaccount;

//定义

mapforaccount lunch;

//赋值

lunch[“陈勇”]=50.00;

lunch[“林立坚”]=35.00;

lunch[“陈阵”]=45.00;

lunch[“czzs”]=65.00;

//打印

mapforaccount::iterator pos;

for(pos=lunch.begin();pos!=lunch.end();++pos)

{

    cout<<“姓名:”<<pos->first<<”/t”

        <<”余额:”<<pos->second<<endl;

}

上述各种容器都有一些成员函数,支持一些基本的操作和对某些算法进行优化。

不同的容器的成员函数并不完全相同。

其中:

 

l         所有容器都支持以下操作符:==,!=,<,>,<=,>=。当且仅当两个容器类型相同,元素数目相同,元素顺序相同,并每个元素都相等时==为true。

小于的情况以字典序进行判定。

l         insert(),push_front(),push_back()等添加成员得函数

l         remove(),pop_front(),pop_back(),[],at()等删除及读取元素的函数。

总之这些函数使你对容器中元素得读写更为方便。

 

剩下得成员函数,诸如sort(),merge()等是容器根据本身特性对某些算法得优化,实现与下面所讲得算法相同得功能。

 

可作为动态数组的vector 非常的常用,以他为例来看一下容器都可以为我们做些什么。

 

构造与析构

vector<Elem> c                 产生一个空vector

vector<Elem> c1(c2)      生成一个c2的副本

vector<Elem> c(n)         产生一大小为n的容器,用缺省构造函数生成其中每个元素的值

vector<Elem> c(n,elem)    产生一大小为n的容器,其中每个元素的值都是elem

vector<Elem> c(beg,end)   产生一个以[beg,end]区间为初值的vector

c.~vector<Elem>()        销毁所有元素,并释放内存

 

非变动性操作

c.size()                返回容器中元素的数量

c.empty()              大小是否为0

c.max_size()           可容纳元素的最大数量

capacity()             重新分配空间前所能容纳的元素的最大数量

reserve()              保留一定大小的空间

c1==c2

c1!=c2

c1<c2

c1>c2

c1<=c2

c1>=c2

 

赋值操作

c1=c2                      将c2的元素全部复制给c1

c.assign(n,elem)           用n个元素填充c

c.assign(beg,end)          用指定区间的内容填充c

c1.swap(c2)               c1,c2的内容互换

swap(c1,c2)               同上为全局函数

 

元素的存取

c.at[idx]                返回索引idx所表示的元素,检查边界

c[idx]                   同上但不检查边界

c.front()                返回第一个元素,不检查其是否存在

c.back()                 返回最后一个元素,不检查其是否存在

 

迭代器相关函数

c.begin()               返回指向第一个元素的随机存取迭代器

c.end()                返回指向最后一个元素的随机存取迭代器

c.rbegin()            返回指向第一个元素的逆向迭代器

c.rend()              返回指向最后一个元素的逆向迭代器

 

安插及移除操作

c.insert(pos,elem)           在pos位置插入一个新元素副本,并返回新元素位置

c.insert(pos,n,elem)        在pos位置插入n个新元素副本

c.insert(pos,beg,end)       在pos位置插入[beg,end)区间内所有元素的副本

c.push_back(elem)          在尾部添加一个elem

c.pop_back()               移除最后一个元素,不回传

c.erase(pos)               移除pos位置的元素,返回下一元素的位置

c.erase(beg,end)           移除[beg,end)区间内所有元素,并传回新位置

c.resize(num)              将元素数量改为num

c.clear()                 移除所有元素

 

 

看如下的程序段:

这是为说明vector各个成员函数的使用而做的。

 

typedef vector<string> stringarray;

 

// PRINT_ELEMENTS负责输出容器中的所有元素

template <class T>

inline void PRINT_ELEMENTS(const T& coll, const char* cptcstr=" ")

    {

    typename T::const_iterator pos;

 

    cout<< cptcstr<< endl;

 

    for(pos=coll.begin();pos!=coll.end();++pos)

        {

        cout<< *pos <<' ';

        cout<<endl;

        }

    }

int main()

    {

        stringarray filename;//empty vector

       

//在容器中的元素数量达到10之前不用重新分配内存

        filename.reserve(10);

 

        filename.push_back("c://test1.emf");

        filename.push_back("c://test2.emf");

        filename.push_back("c://test3.emf");

        filename.push_back("c://test4.emf");

        filename.push_back("c://test5.emf");

        filename.push_back("c://test6.emf");

 

        PRINT_ELEMENTS(filename,"After push_back:");

 

        cout<< "max_size():" <<filename.max_size() <<endl;

        cout<< "size():" <<filename.size() <<endl;

        cout<< "capacity():" <<filename.capacity()<<endl;

//在第一个元素的位置插入

        filename.insert(filename.begin(),"d://ie.emf");

        PRINT_ELEMENTS(filename,"After insert:");

 

        cout<< "Now the first element is: "<< filename[0] << endl;

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

        cout<< "Now the last element is: "<< filename.back() << endl;

 

//为tempfilename赋初值

        stringarray tempfilename=filename;

       

        PRINT_ELEMENTS(tempfilename,"Before erase:");

//删除前三个元素

        tempfilename.erase(tempfilename.begin(),tempfilename.begin()+3);

 

        PRINT_ELEMENTS(tempfilename,"after erase:");

//删除最后一个元素

        tempfilename.pop_back();

 

        PRINT_ELEMENTS(tempfilename,"after pop_back():");

       

//来个恐怖的,这个说明vector在内存中是连续存放的

        vector<char> v;

        v.resize(41);

        strcpy(&v[0],"this is a test");

        printf("%s/n",&v[0]);      

        return 0;

    }

输出结果为:

After push_back:

c:/test1.emf

c:/test2.emf

c:/test3.emf

c:/test4.emf

c:/test5.emf

c:/test6.emf

max_size():357913941

size():6

capacity():10

After insert:

d:/ie.emf

c:/test1.emf

c:/test2.emf

c:/test3.emf

c:/test4.emf

c:/test5.emf

c:/test6.emf

Now the first element is: d:/ie.emf

Now the last element is: c:/test6.emf

Before erase:

d:/ie.emf

c:/test1.emf

c:/test2.emf

c:/test3.emf

c:/test4.emf

c:/test5.emf

c:/test6.emf

after erase:

c:/test3.emf

c:/test4.emf

c:/test5.emf

c:/test6.emf

after pop_back():

c:/test3.emf

c:/test4.emf

c:/test5.emf

this is a test

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值