STL详解(一) 动态数组vector

一、Vectors介绍

 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的.

1.文件包含:      首先在程序开头处加上#include<vector>以包含所需要的类文件vector,    还有一定要加上using namespace std;

2.就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。

3.本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。

4.vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。

5.因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。

6.与其它动态序列容器相比(deques, lists and forward_lists), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和forward_lists统一的迭代器和引用更好。

二、 vector函数列表

1.构造函数

  • vector():创建一个空vector
  • vector(int nSize):创建一个vector,元素个数为nSize
  • vector(int nSize,const t& t):创建一个vector,元素个数为nSize,且值均为t
  • vector(const vector&):复制构造函数
  • vector(begin,end):复制[begin,end)区间内另一个数组的元素到vector中

2.遍历函数

assign() 对Vector中的元素赋值 

at() 返回指定位置的元素

front() 返回第一个元素 

back() 返回最末一个元素 

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

end() 返回最末元素的迭代器(译注:实指向最末元素的下一个位置) 

rbegin() 返回Vector尾部的逆迭代器 

rend() 返回Vector起始的逆迭代器 

3.增加删除函数

pop_back() 移除最后一个元素 

erase() 删除指定元素 

clear() 清空所有元素 

push_back() 在Vector最后添加一个元素 

insert() 插入元素到Vector中 

4.大小函数

size() 返回Vector元素数量的大小 

empty() 判断Vector是否为空(返回true时为空) 

max_size() 返回Vector所能容纳元素的最大数量(上限) 

capacity() 返回vector所能容纳的元素数量(在不重新分配内存的情况下

5.其他函数

get_allocator() 返回vector的内存分配器 

reserve() 设置Vector最小的元素容纳数量 

resize() 改变Vector元素数量的大小 

swap() 交换两个Vector

6.运算符

C++ Vectors能够使用标准运算符: ==, !=, <=, >=, <, 和 >

 三、 函数详细说明 

3.1、 vector声明及初始化

vector<int> vec;        //声明一个int型向量vec
vector<int> vec(5);     //声明一个初始大小为5个成员的int向量vec
vector<int> vec(10, 1); //声明一个初始大小为10个成员且值都是1的向量vec
vector<int> vec(tmp);   //声明并用tmp向量初始化vec向量
vector<int> tmp(vec.begin(), vec.begin() + 3);  //用向量vec的第0个到第2个值初始化tmp
int arr[5] = {1, 2, 3, 4, 5};   
vector<int> vec(arr, arr + 5); //将arr数组的元素用于初始化vec向量
                               //说明:当然不包括arr[4]元素,末尾指针都是指结束元素的下一个元素,                            
                               //这个主要是为了和vec.end()指针统一。
vector<int> vec(&arr[1], &arr[4]); //将arr[1]~arr[4]范围内的元素作为vec的初始值

3.2 元素的访问与迭代器访问

  • 下标访问: vec[1]; //像数组一样用下标访问,但下标访问不会检查是否越界。
  • at方法访问: vec.at(1); //与下标访问的区别就是at会检查是否越界,是则抛出out of range异常
  • 访问第一个元素: vec.front();
  • 访问最后一个元素: vec.back();
  • 开始指针:vec.begin();
  • 末尾指针:vec.end(); //指向最后一个元素的下一个位置
  • 指向常量的开始指针: vec.cbegin(); //意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。
  • 指向常量的末尾指针: vec.cend();

 3.2.1  at()函数 

  语法: TYPE at( size_type loc );

  at() 函数 返回当前Vector指定位置loc的元素的引用。

  at() 函数 比 [ ] 运算符更加安全, 因为它不会让你去访问到Vector内越界的元素。例如, 考虑下面的代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{  vector<int> v(5,1);
   for(int i=0; i<10;i++)
      cout<<"v"<<i<<" is "<<v[i]<<endl;
}

输出:

  这段代码访问了vector末尾以后的元素,这将可能导致很危险的结果.以下的代码将更加安全: 
 

#include<bits/stdc++.h>
using namespace std;
int main()
{  
   vector<int> v(5,1);
   for(int i=0; i<10;i++)
      cout<<"v"<<i<<" is "<<v.at(i)<<endl;
}

输出:


取代试图访问内存里非法值的作法,at() 函数能够辨别出访问是否越界并在越界的时候抛出一个异常out_of_range。

3.2.2 back() 与front()函数 

语法: 
TYPE back(); 
back() 函数返回当前vector最末一个元素的引用。

语法: 
TYPE front();
front() 函数返回当前vector第一个元素的引用.例如: 

#include<bits/stdc++.h>
using namespace std;
int main()
{  
  vector<int> v;
  for(int i=0; i<5;i++)
   v.push_back(i);
  cout<<"The first is "<<v.front()
      <<"   and the last is "<<v.back()<<endl;
}

输出:


3.2.3 begin() 与end()函数 

语法: 
iterator begin();
begin()函数返回一个指向当前vector起始元素的迭代器.例如,下面这段使用了一个迭代器来显示出vector中的所有元素:

语法: 
iterator end();

end() 函数返回一个指向当前vector末尾元素的下一位置的迭代器.注意,如果你要访问末尾元素,需要先将此迭代器自减1.

#include<bits/stdc++.h>
using namespace std;
int main()
{  vector<int> v1(5,789);
   vector<int>::iterator it;
   for(it=v1.begin();it!=v1.end();it++)
      cout<<*it<<endl;
}

输出:

3.3 运算符

C++ Vectors能够使用标准运算符: ==, !=, <=, >=, <, 和 >
语法: 
v1 == v2    v1 != v2   v1 <= v2  v1 >= v2  v1 < v2  v1 > v2 

如果两个vectors被认为是相等的:则它们具有相同的容量 ,所有相同位置的元素相等。
vectors之间大小的比较是按照词典规则.。

3.4 修改

  • 多个元素赋值: vec.assign(); //类似于初始化时用数组进行赋值
  • 末尾添加元素: vec.push_back();
  • 末尾删除元素: vec.pop_back();
  • 任意位置插入元素: vec.insert();
  • 任意位置删除元素: vec.erase();
  • 交换两个向量的元素: vec.swap();
  • 清空向量元素: vec.clear();

3.4.1 assign()函数 

语法: 
1、void assign( input_iterator start, input_iterator end );
2、void assign( size_type num, const TYPE &val );

第一个相当于个拷贝函数,把first到last的值赋值给调用者;(注意区间的闭合)
第二个把n个x赋值给调用者;

1、下面的例子展示了如何将区间[start, end)中的值使用assign()拷贝给调用者:

#include<bits/stdc++.h>
using namespace std;
int main()
{   vector<int> v1;
    for(int i=0; i<10; i++)    v1.push_back(i);
    vector<int>v2;
    v2.assign(v1.begin(),v1.end());//将v1的[beg; end)区间中的数据赋值给调用者v2。
    for(int i=0; i<v2.size(); i++)
      cout<<v2[i]<<" ";
    cout<<endl;
}

运行后输出:

 

2、函数assign()将num个val的副本赋值给当前的vector. 此函数将销毁先前vector中的内容.

例如, 下面的代码使用assign()将10个整数值42的副本赋值给vector:

#include<bits/stdc++.h>
using namespace std;
int main()
{ vector<int> v;
  v.assign(10,42);
  for(int  i=0; i<v.size();i++)
  {cout<<v[i]<<" ";}
  cout<<endl;
}

输出:

3.4.2 clear() 函数 

语法: 
void clear(); clear()函数删除当前vector中的所有元素.

#include<bits/stdc++.h>
using namespace std;
int main()
{  vector<int>obj;
   for(int i=0;i<10;i++)//push_back(elem)在数组最后添加数据 
    {   obj.push_back(i);
        cout<<obj[i]<<",";
    } 
    obj.clear();//清除容器中所以数据
    for(int i=0;i<obj.size();i++)
       cout<<obj[i]<<endl;
}

3.4.3 empty ()函数 

语法: 
bool empty();

如果当前vector没有容纳任何元素,则empty()函数返回true,否则返回false.例如,以下代码清空一个vector,并按照逆序显示所有的元素:

#include<bits/stdc++.h>
using namespace std;
int main()
{  vector<int> v;
   for(int i=0; i<5;i++)
      v.push_back(i);
   while(!v.empty())
   {  cout<<v.back()<<endl;
      v.pop_back();
   }
}


3.4.4 erase ()函数 

语法: 
1、iterator erase( iterator loc );     

如:v1.erase( v1.begin( ) );//删除v1中的第一个元素。

  vec.erase(vec.begin()+2);删除第3个元素。


2、iterator erase( iterator start, iterator end );

如:v1.erase(v1.begin() + 1, v1.begin() + 4); //删除v1.[1] v1.[2] v1.[3]三个元素

  vec.erase(vec.begin()+i,vec.begin()+j);删除区间 [ i, j-1);区间从0开始


erase函数要么删作指定位置loc的元素,要么删除区间[start, end)的所有元素.返回值是指向删除的最后一个元素的下一位置的迭代器.

例如:

// 创建一个vector,置入字母表的前十个字符

#include<bits/stdc++.h>
using namespace std;
int main()
{  vector <char> a;
   for(int i=0;i<10;i++)
     a.push_back(i+65);
   int size =a.size();
   vector<char>::iterator s;
   vector<char>::iterator t;
   for(int i=0; i<size;i++)
   { s=a.begin();
     a.erase(s);
     //Display the vector
     for(t=a.begin();t!=a.end();t++)
       cout<<*t;
     cout<<endl;
    }
}

这段代码将会输出:

#include<bits/stdc++.h>
using namespace std;
int main()
{  using namespace std;
   vector <int> v1;
   vector <int>::iterator Iter;
   v1.push_back(10);
   v1.push_back(20);
   v1.push_back(30);
   v1.push_back(40);
   v1.push_back(50);
   cout << "v1 =";
   for(Iter = v1.begin(); Iter != v1.end(); Iter++)
      cout << " " << *Iter;
   cout << endl;
   v1.erase(v1.begin());//删除v1的第一个元素
   cout << "v1 =";
   for(Iter = v1.begin(); Iter != v1.end(); Iter++)
      cout << " " << *Iter;
   cout << endl;
   //删除v1.begin() + 1和v1.begin() + 2两个元素
   v1.erase(v1.begin() + 1, v1.begin() + 3);
   cout << "v1 =";
   for(Iter = v1.begin(); Iter != v1.end(); Iter++)
     cout << " " << *Iter;
   cout << endl;
}

这段代码将会输出:

3.4.5 insert() 函数 

语法: 
iterator insert( iterator loc, const TYPE &val );
void insert( iterator loc, size_type num, const TYPE &val );
void insert( iterator loc, input_iterator start, input_iterator end );
insert() 函数有以下三种用法: 
在指定位置loc前插入值为val的元素,返回指向这个元素的迭代器, 
在指定位置loc前插入num个值为val的元素 
在指定位置loc前插入区间[start, end)的所有元素 . 
举例: 
//创建一个vector,置入字母表的前十个字符

 

#include<bits/stdc++.h>
using namespace std;
int main()
{  vector <char> a;
   for(int i=0;i<10;i++)
   a.push_back(i+65);
   //插入四个C到vector中
   vector<char>::iterator t = a.begin();
   a.insert(t,4,'C');
   //显示vector的内容
   for(t=a.begin();t!=a.end();t++)
   cout<<*t;
}

这段代码将显示: 
 

#include<bits/stdc++.h>
using namespace std;
int main()  
{  vector<int> v(3);  
   v[0]=2;  
   v[1]=7;  
   v[2]=9;  
   v.insert(v.begin(),8);//在最前面插入新元素。  
   v.insert(v.begin()+2,1);//在迭代器中第二个元素前插入新元素  
   v.insert(v.end(),3);//在向量末尾追加新元素。  
   vector<int>::iterator it;  
   for(it=v.begin(); it!=v.end();it++)  
      cout<<*it<<" ";  
   cout<<endl;
}  

3.4.6 pop_back () 函数

语法: 
void pop_back();
pop_back()函数删除当前vector最末的一个元素,例如:

#include<bits/stdc++.h>
using namespace std;
int main()
{  vector <char> a;
   for(int i=0;i<10;i++)
   a.push_back(i+65);
   int size=a.size();
   vector<char>::iterator t;
   for(int i=0;i<size;i++)
   {  a.pop_back();
      for(t=a.begin();t!=a.end();t++)
        cout<<*t;
      cout<<endl;
   }
}

这段代码将输出:

3.4.7 push_back() 函数 

语法: 
void push_back( const TYPE &val );
push_back()添加值为val的元素到当前vector末尾

#include<bits/stdc++.h>
using namespace std;
struct temp 
{  public : string str ;  
   public : int id ; 
}tmp ;
int main()
{  vector <temp> t ; 
   temp w1 ;  
   w1.str = "Hellowor" ;
   w1.id = 1 ;  
   t.push_back(w1); 
   cout << w1.str << "," <<w1.id <<endl ; 
} 

这段代码将输出:

3.4.8 rbegin() 函数

语法: 
reverse_iterator rbegin();
rbegin函数返回指向当前vector末尾的逆迭代器.(实际指向末尾的下一位置,而其内容为末尾元素的值,详见逆代器相关内容)
示例:

 

#include<bits/stdc++.h>
using namespace std;
int main()
{  vector<int>v1;
   for(int i=1;i<=5;i++)
      v1.push_back(i);
   vector<int>::reverse_iterator pos;
   pos=v1.rbegin();
   cout<<*pos<<" ";
   pos++;
   cout<<*pos<<endl;
}

输出结果为:

3.4.9 rend() 函数

语法: 
reverse_iterator rend();
rend()函数返回指向当前vector起始位置的逆迭代器. 
示例:

#include<bits/stdc++.h>
using namespace std;
int main()
{  vector<int>v1;
   for(int i=1;i<=5;i++)
     v1.push_back(i);
   vector<int>::reverse_iterator pos;
   pos=v1.rend();
   pos--;
   cout<<*pos<<" ";
   pos--;
   cout<<*pos<<endl;
}

输出结果为:1 2


3.4.10 reserve() 函数

语法: 
void reserve( size_type size );
reserve()函数为当前vector预留至少共容纳size个元素的空间.(译注:实际空间可能大于size)


3.4.11 resize() 函数

语法: 
void resize( size_type size, TYPE val );
resize() 函数改变当前vector的大小为size,且对新创建的元素赋值val

resize 与reserve的区别
    reserve是容器预留空间,但并不真正创建元素对象,在创建对象之前,不能引用容器内的元素,因此当加入新的元素时,需要用push_back()/insert()函数。
    resize是改变容器的大小,并且创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,或者用迭代器来引用元素对象。再者,两个函数的形式是有区别的,reserve函数之后一个参数,即需要预留的容器的空间;resize函数可以有两个参数,第一个参数是容器新的大小,第二个参数是要加入容器中的新元素,如果这个参数被省略,那么就调用元素对象的默认构造函数。
初次接触这两个接口也许会混淆,其实接口的命名就是对功能的绝佳描述,resize就是重新分配大小,reserve就是预留一定的空间。这两个接口即存在差别,也有共同点。下面就它们的细节进行分析。
     为实现resize的语义,resize接口做了两个保证:
            一是保证区间[0, new_size)范围内数据有效,如果下标index在此区间内,vector[indext]是合法的。
             二是保证区间[0, new_size)范围以外数据无效,如果下标index在区间外,vector[indext]是非法的。
     reserve只是保证vector的空间大小(capacity)最少达到它的参数所指定的大小n。在区间[0, n)范围内,如果下标是index,vector[index]这种访问有可能是合法的,也有可能是非法的,视具体情况而定。
     resize和reserve接口的共同点是它们都保证了vector的空间大小(capacity)最少达到它的参数所指定的大小。
因两接口的源代码相当精简,以至于可以在这里贴上它们:
void resize(size_type new_size) { resize(new_size, T()); }
void resize(size_type new_size, const T& x) {
    if (new_size < oldsize) 
      erase(oldbegin + new_size, oldend); // erase区间范围以外的数据,确保区间以外的数据无效
    else
      insert(oldend, new_size - oldsize, x); // 填补区间范围内空缺的数据,确保区间内的数据有效
示例:

 

#include<bits/stdc++.h>
using namespace std;
int main()
{   int i;
    vector<int>v1;
    for( i=1;i<=3;i++)
      v1.push_back(i);
    v1.resize(5,8);//多出的两个空间都初始化为8,
    for( i=0;i<v1.size();i++)//resize与reserver并不会删除原先的元素以释放空间
       cout<<v1[i]<<" ";
    cout<<endl;
    v1.reserve(7);//新元素还没有构造,
    for(i=0;i<7;i++)
      cout<<v1[i]<<" ";//当i>4,此时不能用[]访问元素?
    cout<<endl;
    cout<<v1.size()<<endl;
    cout<<v1.capacity()<<endl;
}

输出结果为:
 

3.4.12 swap() 函数

语法: 
void swap( vector &from );
swap()函数交换当前vector与vector from的元素
示例:
     

#include<bits/stdc++.h>
using namespace std;
int main()
{   vector<int>v1,v2;
    for(int i=1;i<=3;i++)
    {  v1.push_back(i);
       v2.push_back(i);
    }
    v2.push_back(4);
    v2.push_back(5);
    v1.swap(v2);
    for(int j=0;j<v1.size();j++)
       cout<<v1[j]<<" ";
    cout<<endl;
    for(int k=0;k<v2.size();k++)
      cout<<v2[k]<<" ";
    cout<<endl;
}

输出结果为:
 

3.4.13 get_allocator ()函数 

语法: 
allocator_type get_allocator();
get_allocator() 函数返回当前vector的内存分配器.在STL里面一般不会调用new或者alloc来分配内存,而且通过一个allocator对象的相关方法来分配.
示例:vector<int>v3( 3, 1, v2.get_allocator( ));

     //把V2的内存分配器作为一个参数参与构造V3。这样,它们两个用一个内存分配器了。

3.5 容量

  • 向量大小: vec.size();                   //当前使用数据的大小
  • 向量最大容量: vec.max_size();  //改变Vector元素数量的大小 
  • 更改向量大小: vec.resize();
  • 向量真实大小: vec.capacity();
  • 向量判空: vec.empty();               //  判断Vector是否为空(返回true时为空)
  • 减少向量大小到满足元素所占存储空间的大小: vec.shrink_to_fit(); 

四、排序

#include<bits/stdc++.h>
using namespace std;
int main()
{   vector<int>obj;
    obj.push_back(1);
    obj.push_back(3);
    obj.push_back(0);
    sort(obj.begin(),obj.end());//从小到大
    cout<<"从小到大:"<<endl;
    for(int i=0;i<obj.size();i++)
       cout<<obj[i]<<",";  
    cout<<"\n"<<endl;
    cout<<"从大到小:"<<endl;
    reverse(obj.begin(),obj.end());//从大到小 
    for(int i=0;i<obj.size();i++)
       cout<<obj[i]<<",";
    return 0;
}

输出结果为:

五、二维数组两种定义方法(结果一样)

 方法一:

#include<bits/stdc++.h>
using namespace std;
int main()
{   int N=5, M=6; 
    vector<vector<int> > obj(N); //定义二维动态数组大小5行 
    for(int i =0; i< obj.size(); i++)//动态二维数组为5行6列,值全为0 
       obj[i].resize(M); 
    for(int i=0; i< obj.size(); i++)//输出二维动态数组 
    {   for(int j=0;j<obj[i].size();j++)
            cout<<obj[i][j]<<" ";
        cout<<"\n";
    }
}

 方法二:

#include<bits/stdc++.h>
using namespace std;
int main()
{   int N=5, M=6; 
    vector<vector<int> > obj(N, vector<int>(M)); //定义二维动态数组5行6列 
    for(int i=0; i< obj.size(); i++)//输出二维动态数组 
    {  for(int j=0;j<obj[i].size();j++)
          cout<<obj[i][j]<<" ";
       cout<<"\n";
    }
}

六、应用举例:

6.1、中间数

【问题描述】

依次读入若干正整数,如果是奇数个就输出最中间的那个数;否则,输出中间两个数的和。以 0 作为结束标志,但 0 不计数。

6.2、上网统计

【问题描述】

在一个网络系统中有 N 个用户、M 次上网记录。每个用户可以自己注册一个用户名,每个用户名是一个只含小写字母且长度小于 1000 的字符串。每个上网的账号每次上网都会浏览网页,网页名是以一个只含小写字母且长度小于 1000 的字符串,每次上网日志里都会有记录,现在请统计每个用户每次浏览了多少个网页。

【输入格式】

第 1 行包含两个用 1 个空格隔开的正整数 N(1≤N≤1000)和 M(1≤M≤5000)。

第 2~M+1 行,每行包含 2 个用 1 个空格隔开的字符串,分别表示用户名和浏览的网页名。

【输出格式】

共 N 行,每行的第一个字符串是用户名,接下来的若干字符串是这个用户依次浏览的网页名(之间用一个空格隔开)。按照用户名出现的次序排序输出。

【输入样例】

5 7

goodstudyer bookshopa

likespacea spaceweb

goodstudyer bookshopb

likespaceb spaceweb

likespacec spaceweb

likespacea juiceshop

gameplayer gameweb

【输出样例】

goodstudyer bookshopa bookshopb

likespacea spaceweb juiceshop

likespaceb spaceweb

likespacec spaceweb

gameplayer gameweb

6.3、蛇形方阵

【问题描述】

输入 n,n≤100,输出 n 阶蛇形方阵。例如 n=5 时,输出如下:

1   2    6   7  15

3   5    8  14 16

4   9   13 17 22

10 12 18 21 23

11 19 20 24 25

6.4、钻石收藏家

奶牛Bessie很喜欢闪亮亮的东西,所以她喜欢在她的空余时间开采钻石!她现在已经收集了N颗不同大小的钻石(N<=50,000),现在她想在谷仓的两个陈列架上摆放一些钻石。Bessie想让这些陈列架上的钻石保持相似的大小,所以她不会把两个大小相差   K  以上的钻石同时放在一个陈列架上(如果两颗钻石的大小差值为K,那么它们可以同时放在一个陈列架上)。现在给出K,请你帮Bessie确定她最多一共可以放多少颗钻石在这两个陈列架上。

输入输出格式

输入格式:

第一行2个正整数N和K,之间用一个空格隔开。

接下来的N行,每行包括1个正整数Si ,描述第i颗钻石的大小。

输出格式:

一行一个整数,表示Bessie最多能选出多少颗钻石在盒子里展览。

输入输出样例

输入样例#1: 

7 3
10
5
1
12
9
5
14

输出样例#1: 

5

第一篇 预备知识 第1章 C++编程技术 2 1.1 类和对象 2 1.2 类的继承 5 1.3 函数重载 5 1.4 访问控制 7 1.5 操作符重载 8 1.6 显式类型转换 9 1.7 异常处理 13 1.8 名字空间 17 1.9 友员函数 20 1.10 内联函数 21 1.11 静态成员 22 1.12 本章小结 23 第2章 C++模板技术 25 2.1 函数模板 25 2.2 类模板 27 2.3 模板完全特化 28 2.4 函数模板重载 30 2.5 类模板继承 30 2.6 本章小结 31 第3章 C++ I/O流技术 32 3.1 I/O流类 32 3.2 标准输入输出 34 3.3 文件输入输出 36 3.4 流的格式控制 41 3.5 本章小结 45 第二篇 C++ STL泛化技术基础 第4章 C++ STL泛型库概述 48 4.1 C++ STL的发展历程 48 4.2 C++ STL的各种实现版本 49 4.2.1 HP STL 49 4.2.2 SGI STL 50 4.2.3 STLport 50 4.2.4 P.J.Plauger STL 50 4.2.5 Rouge Wave STL 50 4.3 C++ STL的Visual C++编译 50 4.4 C++ STL的体系结构 52 4.4.1 容器(Container) 52 4.4.2 迭代器(Iterator) 53 4.4.3 算法(Algorithm) 53 4.4.4 函数对象(Function Object) 54 4.4.5 适配器(Adapter) 55 4.4.6 内存分配器(Allocator) 56 4.4.7 概念(Concept)和模型(Model) 56 4.5 C++ STL存在的一些问题 57 4.6 本章小结 57 第5章 C++ STL泛化技术分析 58 5.1 算法和迭代器 58 5.1.1 算法 58 5.1.2 迭代器 61 5.1.3 函数对象 65 5.1.4 适配器 68 5.2 内存分配器和容器 74 5.2.1 内存分配器 75 5.2.2 容器 77 5.3 概念 82 5.3.1 基础性概念 82 5.3.2 容器概念 84 5.3.3 迭代器概念 86 5.3.4 函数对象概念 88 5.4 本章小结 89 第三篇 C++ STL容器技术 第6章 vector向量容器 92 6.1 vector技术原理 92 6.2 vector应用基础 94 6.3 本章小结 101 第7章 deque双端队列容器 102 7.1 deque技术原理 102 7.2 deque应用基础 108 7.3 本章小结 115 第8章 list双向链表容器 116 8.1 list技术原理 116 8.2 list应用基础 124 8.3 本章小结 131 第9章 slist单向链表容器 132 9.1 slist技术原理 132 9.2 slist应用基础 140 9.3 本章小结 148 第10章 bit_vector位向量容器 149 10.1 bit_vector技术原理 149 10.2 bit_vector应用基础 156 10.3 本章小结 161 第11章 set集合容器 162 11.1 set技术原理 162 11.2 set应用基础 181 11.3 本章小结 186 第12章 multiset多重集合容器 187 12.1 multiset技术原理 187 12.2 multiset应用基础 190 12.3 本章小结 196 第13章 map映照容器 197 13.1 map技术原理 197 13.2 map应用基础 200 13.3 本章小结 206 第14章 multimap多重映照容器 207 14.1 multimap技术原理 207 14.2 multimap应用基础 210 14.3 本章小结 216 第15章 hash_set哈希集合容器 217 15.1 hash_set技术原理 217 15.2 hash_set应用基础 230 15.3 本章小结 234 第16章 hash_map哈希映照容器 235 16.1 hash_map技术原理 235 16.2 hash_map应用基础 237 16.3 本章小结 242 第17章 string基本字符序列容器 243 17.1 string技术原理 243 17.2 string应用基础 258 17.3 本章小结 264 第18章 stack堆栈容器 265 18.1 stack技术原理 265 18.2 stack应用基础 266 18.3 本章小结 269 第19章 queue队列容器 270 19.1 queue技术原理 270 19.2 queue应用基础 271 19.3 本章小结 274 第20章 priority_queue优先队列容器 275 20.1 priority_queue技术原理 275 20.2 priority_queue应用基础 278 20.3 本章小结 281 第四篇 C++ STL算法技术 第21章 非变易算法 284 21.1 逐个容器元素for_each 284 21.2 查找容器元素find 285 21.3 条件查找容器元素find_if 286 21.4 邻近查找容器元素adjacent_find 287 21.5 范围查找容器元素find_first_of 289 21.6 统计等于某值的容器元素个数count 290 21.7 条件统计容器元素个数count_if 291 21.8 元素不匹配查找mismatch 293 21.9 元素相等判断equal 295 21.10 子序列搜索search 296 21.11 重复元素子序列搜索search_n 299 21.12 最后一个子序列搜索find_end 301 21.13 本章小结 303 第22章 变易算法 304 22.1 元素复制copy 304 22.2 反向复制copy_backward 305 22.3 元素交换swap 306 22.4 迭代器交换iter_swap 307 22.5 区间元素交换swap_ranges 308 22.6 元素变换transform 309 22.7 替换 310 22.8 条件替换replace_if 311 22.9 替换和复制replace_copy 312 22.10 条件替换和复制replace_copy_if 313 22.11 填充fill 314 22.12 n次填充fill_n 315 22.13 随机生成元素generate 316 22.14 随机生成n个元素generate_n 317 22.15 移除复制remove_copy 318 22.16 条件移除复制remove_copy_if 319 22.17 移除remove 320 22.18 条件移除remove_if 321 22.19 不连续重复元素复制unique_copy 322 22.20 剔除连续重复元素unique 324 22.21 元素反向reverse 325 22.22 反向复制reverse_copy 326 22.23 旋转rotate 327 22.24 旋转复制rotate_copy 329 22.25 随机抖动random_shuffle 330 22.26 随机采样random_sample 331 22.27 容器分割partition 333 22.28 容器稳定分割stable_partition 335 22.29 本章小结 338 第23章 排序算法 339 23.1 元素入堆push_heap 339 23.2 创建堆make_heap 343 23.3 元素出堆pop_heap 348 23.4 堆排序sort_heap 351 23.5 是否为堆is_heap 352 23.6 局部排序partial_sort 354 23.7 局部排序复制partial_sort_copy 356 23.8 排序sort 359 23.9 归并merge 366 23.10 内部归并inplace_merge 368 23.11 稳定排序stable_sort 376 23.12 是否排序is_sorted 383 23.13 第n个元素nth_element 384 23.14 下确界lower_bound 386 23.15 上确界upper_bound 388 23.16 等价区间equal_range 390 23.17 折半搜索binary_search 392 23.18 子集合includes 393 23.19 集合求并set_union 394 23.20 集合求交set_ intersection 396 23.21 集合求差set_difference 398 23.22 集合求异set_symmetric_difference 399 23.23 最小值min 401 23.24 最大值max 402 23.25 最小元素min_element 403 23.26 最大元素max_element 404 23.27 字典比较lexicographical_compare 405 23.28 下一排列组合next_permutation 406 23.29 上一排列组合prev_permutation 409 23.30 本章小结 411 第24章 数值算法 412 24.1 递增赋值iota 412 24.2 元素求和accumulate 413 24.3 两序列元素内积inner_product 414 24.4 部分元素求和partial_sum 415 24.5 相邻元素求差adjacent_difference 417 24.6 n次方计算power 419 24.7 本章小结 421 第五篇 C++ STL迭代器技术 第25章 输入输出流迭代器 424 25.1 输入流迭代器 424 25.2 输出流迭代器 426 25.3 本章小结 427 第26章 插入/反向/存储迭代器 428 26.1 向前插入迭代器 428 26.2 向后插入迭代器 429 26.3 插入迭代器 431 26.4 反向迭代器 432 26.5 反向双向迭代器 434 26.6 原始存储迭代器 435 26.7 本章小结 437 附录 STL版权说明 438
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值