2.2 vector向量容器

vector向量容器不但能像数组一样对元素进行随机访问,还能在尾部插入元素,是一种简单、高效的容器,完全可以代替数组。

值得注意的是,vector具有内存自动管理的功能,对于元素的插入和删除,可动态调整所占的内存空间。

使用vector向量容器,需要头文件包含声明“#include <vector>”。vector文件在C:\Program Files\Microsoft Visual Studio\VC98\Include文件夹中可以找到。

vector容器的下标是从0开始计数的,也就是说,如果vector容器的大小是n,那么,元素的下标是0~n-1。对于vector容器的容量定义,可以事先定义一个固定大小,事后,可以随时调整其大小;也可以事先不定义,随时使用push_back()方法从尾部扩张元素,也可以使用insert()在某个元素位置前插入新元素。

vector容器有两个重要的方法,begin()和end()。begin()返回的是首元素位置的迭代器;end()返回的是最后一个元素的下一元素位置的迭代器。

2.2.1 创建vector对象

创建vector对象常用的有三种形式。

(1)不指定容器的元素个数,如定义一个用来存储整型的容器:

        vector<int> v;

(2)创建时,指定容器的大小,如定义一个用来存储10个double类型元素的向量容器:

        vector<double> v(10);

注意,元素的下标为0~9;另外,每个元素的值被初始化为0.0。

(3)创建一个具有n个元素的向量容器对象,每个元素具有指定的初始值:

        vector<double> v(10,8.6);

上述语句定义了v向量容器,共有10个元素,每个元素的值是8.6。

2.2.2 尾部元素扩张

通常使用push_back()对vector容器在尾部追加新元素。尾部追加元素,vector容器会自动分配新内存空间。可对空的vector对象扩张,也可对已有元素的vector对象扩张。

下面的代码将2,7,9三个元素从尾部添加到v容器中,这样,v容器中就有三个元素,其值依次是2,7,9。

        #include <vector>
        using namespace std;

       int main(int argc, char * argv[])
        {
          vector<int> v;
          v.push_back(2);
          v.push_back(7);
          v.push_back(9);
          return 0;
        }

2.2.3 下标方式访问vector元素

访问或遍历vector对象是常要做的事情。对于vector对象,可以采用下标方式随意访问它的某个元素,当然,也可以以下标方式对某元素重新赋值,这点类似于数组的访问方式。

下面的代码就是采用下标方式对数组赋值,再输出元素的值2,7,9:

        #include <vector>
        #include <iostream>
        using namespace std;

       int main(int argc, char * argv[])
        {
          vector<int> v(3);
          v[0]=2;
          v[1]=7;
          v[2]=9;
          cout<<v[0]<<" "<<v[1]<<" "<<v[2]<<endl;
          return 0;
        }

2.2.4 用迭代器访问vector元素

常使用迭代器配合循环语句来对vector对象进行遍历访问,迭代器的类型一定要与它要遍历的vector对象的元素类型一致。

下面的代码采用迭代器对vector进行了遍历,输出2,7,9:

        #include <vector>
        #include <iostream>
        using namespace std;

       int main(int argc, char * argv[])
        {
          vector<int> v(3);
          v[0]=2;
          v[1]=7;
          v[2]=9;
          //定义迭代器变量
          vector<int>::iterator it;
          for(it=v.begin(); it! =v.end(); it++)
          {
              //输出迭代器上的元素值
              cout<<*it<<" ";
          }
          //换行
          cout<<endl;
          return 0;
        }

2.2.5 元素的插入

insert()方法可以在vector对象的任意位置前插入一个新的元素,同时,vector自动扩张一个元素空间,插入位置后的所有元素依次向后挪动一个位置。

要注意的是,insert()方法要求插入的位置,是元素的迭代器位置,而不是元素的下标。

下面的代码输出的结果是8,2,1,7,9,3:

        #include <vector>
        #include <iostream>
        using namespace std;

       int main(int argc, char * argv[])
        {
          vector<int> v(3);
          v[0]=2;
          v[1]=7;
          v[2]=9;
          //在最前面插入新元素,元素值为8
          v.insert(v.begin(),8);
          //在第2个元素前插入新元素1
          v.insert(v.begin()+2,1);
          //在向量末尾追加新元素3
          v.insert(v.end(),3);
          //定义迭代器变量
          vector<int>::iterator it;
          for(it=v.begin(); it! =v.end(); it++)
          {
              //输出迭代器上的元素值
              cout<<*it<<" ";
          }
          //换行
          cout<<endl;
          return 0;
        }

2.2.6 元素的删除

erase()方法可以删除vector中迭代器所指的一个元素或一段区间中的所有元素。

clear()方法则一次性删除vector中的所有元素。

下面这段代码演示了vector元素的删除方法:

        #include <vector>
        #include <iostream>
        using namespace std;

       int main(int argc, char * argv[])
        {
          vector<int> v(10);

            //给向量赋值
            for(int i=0; i<10; i++)
            {
                v[i]=i;
            }
            //删除第2个元素,从0开始计数
            v.erase(v.begin()+2);
            //定义迭代器变量
            vector<int>::iterator it;
            for(it=v.begin(); it! =v.end(); it++)
            {
                //输出迭代器上的元素值
                cout<<*it<<" ";
            }
            //换行
            cout<<endl;
            //删除迭代器第1到第5区间的所有元素
            v.erase(v.begin()+1, v.begin()+5);
            for(it=v.begin(); it! =v.end(); it++)
            {
                //输出迭代器上的元素值
                cout<<*it<<" ";
            }
            //换行
            cout<<endl;
            //清空向量
            v.clear();
            //输出向量大小
            cout<<v.size()<<endl;
            return 0;
          }
          运行结果:
          0 1 3 4 5 6 7 8 9
          0 6 7 8 9
          0

2.2.7 使用reverse反向排列算法

reverse反向排列算法,需要定义头文件“#include <algorithm>”, algorithm文件位于C:\Program Files\Microsoft Visual Studio\VC98\Include文件夹中。

reverse算法可将向量中某段迭代器区间元素反向排列,看下面这段代码:

        #include <vector>
        #include <iostream>
        #include <algorithm>
        using namespace std;

       int main(int argc, char * argv[])

        {
          vector<int> v(10);
          //给向量赋值
          for(int i=0; i<10; i++)
          {
              v[i]=i;
          }
          //反向排列向量的从首到尾间的元素
          reverse(v.begin(), v.end());
          //定义迭代器变量
          vector<int>::iterator it;
          for(it=v.begin(); it! =v.end(); it++)
          {
              //输出迭代器上的元素值
              cout<<*it<<" ";
          }
          //换行
          cout<<endl;
          return 0;
        }

输出结果:

        9 8 7 6 5 4 3 2 1 0

2.2.8 使用sort算法对向量元素排序

使用sort算法,需要声明头文件“#include <algorithm>”。

sort算法要求使用随机访问迭代器进行排序,在默认的情况下,对向量元素进行升序排列,下面这个程序很好地说明了sort算法的使用方法:

        #include <vector>
        #include <iostream>
        #include <algorithm>
        using namespace std;

       int main(int argc, char * argv[])
        {
          vector<int> v;
          int i;
          //赋值
          for(i=0; i<10; i++)
          {
              v.push_back(9-i);
          }
          //输出排序前的元素值
          for(i=0; i<10; i++)
          {
              cout<<v[i]<<" ";
          }

            //回车换行
            cout<<endl;
            //排序,升序排列
            sort(v.begin(), v.end());
            //输出排序后的元素值
            for(i=0; i<10; i++)
            {
                cout<<v[i]<<" ";
            }
            //回车换行
            cout<<endl;
            return 0;
          }

运行结果:

        9 8 7 6 5 4 3 2 1 0
        0 1 2 3 4 5 6 7 8 9

还可以自己设计排序比较函数,然后,把这个函数指定给sort算法,那么,sort就根据这个比较函数指定的排序规则进行排序。下面的程序自己设计了一个排序比较函数Comp,要求对元素的值由大到小排序:

        #include <vector>
        #include <iostream>
        #include <algorithm>
        using namespace std;

       //自己设计排序比较函数:对元素的值进行降序排列
        bool Comp(const int &a, const int &b)
        {
          if(a! =b)return a>b;
          else return a>b;
        }
        int main(int argc, char * argv[])
        {
          vector<int> v;
          int i;
          //赋值
          for(i=0; i<10; i++)
          {
              v.push_back(i);
          }
          //输出排序前的元素值
          for(i=0; i<10; i++)
          {
              cout<<v[i]<<" ";
          }
          //回车换行
          cout<<endl;
          //按Comp函数比较规则排序

            sort(v.begin(), v.end(), Comp);
            //输出排序后的元素值
            for(i=0; i<10; i++)
            {
                cout<<v[i]<<" ";
            }
            //回车换行
            cout<<endl;
            return 0;
          }

运行结果:

        0 1 2 3 4 5 6 7 8 9
        9 8 7 6 5 4 3 2 1 0

2.2.9 向量的大小

使用size()方法可以返回向量的大小,即元素的个数。

使用empty()方法返回向量是否为空。

下面这段代码演示了size()方法和empty()方法的用法:

        #include <vector>
        #include <iostream>
        #include <algorithm>
        using namespace std;

       int main(int argc, char * argv[])
        {
          vector<int> v(10);
          //给向量赋值
          for(int i=0; i<10; i++)
          {
              v[i]=i;
          }
          //输出向量的大小,即包含了多少个元素
          cout<<v.size()<<endl;
          //输出向量是否为空,如果非空,则返回逻辑假,即0,否则返回逻辑真,即1
          cout<<v.empty()<<endl;
          //清空向量
          v.clear();
          //输出向量是否为空,如果非空,则返回逻辑假,即0,否则返回逻辑真,即1
          cout<<v.empty()<<endl;
          return 0;
        }

运行结果:

        10
        0
        1

向量的使用方法还有很多,这里举出的只是常用的方法,如果需要更为翔实的资料,请大家参考C++STL相关材料。

另外,向量的元素类型可以是int, double, char等简单类型,也可以是结构体或string基本字符序列容器,使用起来非常灵活。