《STL Tutorial Reference》Chapt 5 STL overview

5.1 STL组成
- 容器
- 迭代器
- 算法


STL的概念是基于数据和操作的分离。
数据由容器类管理,操作是由可配置的算法定义,迭代器则是两者的黏合剂

STL的概念和OOP思想是相矛盾的。这样做的原因:理论上,你可以将每种容器和每种算法结合,结果很灵活但仍是非常小的framework.

STL是很好的Generic Programming的例子。

5.2 容器

可以将容器大致划分为2类:
1)序列容器  ordered collections. 3个预定义的序列容器: vector, deque, list
2)关联容器  sorted collections.  4个预定义的关联容器:set, map, multiset, multimap

你可以将关联容器看作特殊的序列容器,因为sorted collections是依据sorting criterion而有序的。关联容器的自动排序并不意味着它们是专为排序设计的,同样,你也可以为序列容器排序。自动排序的优势在于当你搜索元素时有更好的表现。实际上,你总是可以使用二分搜索。

vector:
使用动态数组管理元素,提供随机访问。可以直接通过下标访问,append或remove末尾元素是非常快,但是插入元素到开始或中间很费时。

#include <iostream> 
   #include 
<vector> 
   
using namespace std; 
 
   
int main() 
   { 
       vector
<int> coll;        //vector container for integer elements 
 
       
// append elements with values 1 to 6 
       for (int i=1; i<=6++i) { 
           coll.push_back(i); 
       } 
 
       
//print all elements followed by a space 
       for (int i=0; i<coll.size( ); ++i) { 
           cout 
<< coll[i] << ' '
       } 
       cout 
<< endl; 
   } 

deque:
动态数组实现,可以在两端增长。插入在开头和末尾是非常快。

// stl/deque1.cpp 
 
   #include 
<iostream> 
   #include 
<deque> 
   
using namespace std; 
 
   
int main() 
   { 
       deque
<float> coll; //deque container for floating-point elements 
    
//insert elements from 1.1 to 6.6 each at the front 
       for (int i=1; i<=6++i) { 
           coll.push_front(i
*11);        //insert at the front 
       } 
 
       
//print all elements followed by a space 
       for (int i=0; i<coll.size(); ++i) { 
           cout 
<< coll[i] << ' '
       } 
       cout 
<< endl; 
   } 

list:
实现为一个双端链表。不提供随机访问。插入和移除中间元素非常快。
// stl/list1.cpp 
 
   #include 
<iostream> 
   #include 
<list> 
   
using namespace std; 
   
int main() 
   { 
       list
<char> coll;         //list container for character elements 
 
       
// append elements from 'a' to 'z' 
       for (char c='a'; c<= ' z '++c) { 
           coll.push_back(c); 
       } 
 
       
/* print all elements 
        * - while there are elements 
        * - print and remove the first element 
        
*/ 
       
while (! coll.empty()) { 
           cout 
<< coll.front() << ' '
           coll.pop_front(); 
       } 
       cout 
<< endl; 
   } 

string:
basic_string<>, string, wstring

关联容器会依据某种顺序准则自动排序,默认使用运算符<
关联容器典型的实现为二叉树。这样每个元素有1个parent、2个child。左子树有更小的值,右子树有更大的值。关联容器区分在它们支持的元素的种类以及它们怎样处理重复
set, map, multiset, multimap
   #include <iostream> 
   #include 
<set> 
 
   
int main() 
   { 
       
//type of the collection 
       typedef std::set<int> IntSet; 
 
       IntSet coll;        
//set container for int values 
 
       
/* insert elements from 1 to 6 in arbitray order 
        *- value 1 gets inserted twice 
        
*/ 
       coll.insert(
3); 
       coll.insert(
1); 
       coll.insert(
5); 
       coll.insert(
4); 
       coll.insert(
1); 
       coll.insert(
6); 
       coll.insert(
2); 
 
       
/* print all elements 
        *- iterate over all elements 
        
*/ 
       IntSet::const_iterator pos; 
       
for (pos = coll.begin(); pos != coll.end(); ++pos) { 
           std::cout 
<< *pos << ' '
       } 
       std::cout 
<< std::endl; 
   } 

#include <iostream> 
   #include 
<map> 
   #include 
<string> 
   
using namespace std; 
 
   
int main() 
   { 
       
//type of the collection 
       typedef multimap<intstring> IntStringMMap; 
 
       IntStringMMap coll;       
//set container for int/string values 
 
       
//insert some elements in arbitrary order 
       
//- a value with key 1 gets inserted twice 
       coll.insert(make_pair(5,"tagged")); 
       coll.insert(make_pair(
2,"a")); 
       coll.insert(make_pair(
1,"this")); 
       coll.insert(make_pair(
4,"of")); 
       coll.insert(make_pair(
6,"strings")); 
       coll.insert(make_pair(
1,"is")); 
       coll.insert(make_pair(
3,"multimap")); 
 
       
/* print all element values 
        *- iterate over all elements 
        *- element member second is the value 
        
*/ 
       IntStringMMap::iterator pos; 
       
for (pos = coll.begin(); pos != coll.end(); ++pos) { 
           cout 
<< pos->second << ' '
       } 
       cout 
<< endl; 
   } 

容器适配器:
预定义的3种容器适配器: stack, queue, priority queue

迭代器:
iterator

每个容器提供了相同的基本函数来使用迭代器访问它们的元素:
begin() - 返回指示首元素的iterator或const_iterator
end() - 返回指示尾元素的iterator或const_iterator
看STL实现源码:
      iterator
      begin() { 
return iterator (this->_M_impl._M_start); }

      const_iterator
      begin() 
const { return const_iterator (this->_M_impl._M_start); }

      iterator
      end() { 
return iterator (this->_M_impl._M_finish); }

      const_iterator
      end() 
const { return const_iterator (this->_M_impl._M_finish); }


每个容器定义了2种迭代器类型:
1.  container::iterator
is provided to iterate over elements in read/write mode.
2.  container: : const_iterator
is provided to iterate over elements in read-only mode.

另外,对于iterator的自增、自减推荐采用前置形式,后置形式因为会生成临时对象的原因,会比前置形式慢

iterator分类:
依据容器内部的数据结构,预定义容器的迭代器属于下列类型之一:
1)bidirectional iterator
使用自增或自减提供向前和向后,不支持“迭代器算术”。list/set/map/multiset/multimap
2) random access iterator
具备1)的全部属性,而且可以提供随机访问,支持“迭代器算术”。
for (pos = coll.begin(); pos != coll.end(); ++pos)

     //...


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

     //...
}
第一种都支持,但是第二种只有随机访问iterator支持

5.4 算法
STL提供标准算法,这些算法提供基本的服务:排序,搜索,拷贝,重排序,修改和数字处理

算法不是容器类的成员函数,而是全局函数,以iterator操作。
例:
   #include <iostream> 
   #include 
<vector> 
   #include 
<algorithm> 
   
using namespace std; 
 
   
int main() 
   { 
       vector
<int> coll; 
       vector
<int>::iterator pos; 
 
       
//insert elements from 1 to 6 in arbitrary order 
       coll.push_back(2); 
       coll.push_back(
5); 
       coll.push_back(
4); 
       coll.push_back(
1); 
       coll.push_back(
6); 
       coll.push_back(
3); 
 
       
//find and print minimum and maximum elements 
       pos = min_element (coll.begin(), coll.end()); 
       cout 
<< "min: " << *pos << endl; 
       pos 
= max_element (coll.begin(), coll.end()); 
       cout 
<< "max: " << *pos << endl; 
 
       
//sort all elements 
       sort (coll.begin(), coll.end()); 
 
       
//find the first element with value 3
       pos = find (coll.begin(), coll.end(),  //range 
                   3);                        //value 
 
      
//reverse the order of the found element with value 3 and all following elements 
      reverse (pos, coll.end()); 
 
      
//print all elements 
      for (pos=coll.begin(); pos!=coll.end(); ++pos) { 
          cout 
<< *pos << ' ' ; 
      } 
      cout 
<< endl; 
   } 

5.4.1 范围
所有的算法处理一个或多个范围。范围的有效性依赖于用户:包括范围边界是否可到达、两个iterator是否属于同一个容器、begin iterator处在了end iterator后

所有的算法使用半开范围,即[begin, end)
posted @ 2007-10-27 00:25  中土  阅读(697)  评论(0编辑  收藏  举报
©2005-2008 Suprasoft Inc., All right reserved.