vector 的用法——2018-08-30

1. vector说明

vector相当于动态数组,其大小可以预先不指定,并且可以自动扩展,在创建vector变量后,它会在内存中自动分配一块连续的内存空间来保存数据,初始内存空间可以预先指定,也可以由vector默认指定大小。当存储的数据超过分配的空间时,vector会重新分配一块内存,但是这样的分配比较耗时,重新分配的步骤如下:
1)vector申请一块更大的内存块
2)将原来的数据拷贝到新的内存块中
3)销毁掉原内存块中的对象(调用对象的析构函数)
4)将原来的内存空间释放掉
vector保存的数据量很大时,如果此时进行插入数据导致需要更大的空间来保存这些数据量,那么将会大大地影响程序运行的效率,因此我们应该合理地使用vector

2. vector的初始化

  • vector是 C++ STL的成员,使用时需要包含头文件#include,同时使用标准命名空间std
  • 初始化:
vector a; // 建立一个空的 vector
vector a(10); // 定义了10个整型元素的向量(尖括号中为元素类型名,它可以是任何合法的数据类型),但没有给出初值,其值是不确定的。
vector a(10, 1); // 定义了10个整型元素的向量,且每个元素的初值为1
vector b(a); // 用 a 向量来创建 b 向量,整体复制性赋值
vector b(a.begin(), a.begin() + 3); // 定义了b值为a中第0个到第2个(共3个)元素
vector a = {1,2,3,4,5}; // 定义向量中的元素为1,2,3,4,5共5个元素,这种初始化只在C++11及以上才支持,因此在编译时需要使用支持C++11标准的编译器

int c[7] = {1,2,3,4,5,6,7};
vector a(c, c+7); // 从数组中获得初值

3. vector方法

a.assign(b.begin(), b.begin() + 4); // 将 b 的 0-2 三个元素构成的向量赋给a
a.assign(4, 2); // 向量a 只含有4个元素,且每个元素的值为2
a.back(); // 返回 a 的最后一个元素
a.front(); // 返回 a 的第一个元素
a[i]; // 返回 a 的第 i 个元素,仅用作读取,当且仅当a[i]存在
a.clear(); // 清空 a 中的元素
a.empty(); // 判断向量 a 是否为空,如果为空则返回 true, 否则返回false
a.pop_back(); // 删除向量 a 的最后一个元素
a.push_back(5); // 在向量 a 的最后面添加一个元素
a.insert(a.begin()+5, 3); // 在向量 a 的第5个元素(从第0个算起)添加元素3,其他元素后移
a.insert(a.begin()+1, c, c+6); // c 是数组,在a的第1个元素(从第0个算起)的位置插入 c 的第0个元素到第5个元素(不包括c+6);
a.erase(a.begin() + 1, a.begin() + 3); // 删除向量a中的第1个和第2个元素(从第0个算起,左闭右开),
                                       //erase不会清空删除元素的内存,因此capacity()不变
a.size(); // 返回向量 a 中元素的个数
a.capacity(); // 返回向量 a 申请的内存总共可容纳的元素个数
a.resize(10); // 将 a 现有元素的个数调制10个,即使其size()为10,多则删原来的元素,但是不会释放内存,因此其capacity()不会变化;
              //但少了的话则随机补,此时会申请内存,其size()和capacity()相同。
a.resize(10, 2); //将向量 a 的 size()调为10,多则删,如果少了则补 2
a.reserve(100); // 给 a 的capacity()扩充至 100 个元素,这种操作只有在需要给a添加大量数据的时候才显得有意义,
                //因为这将避免内存多次容量扩充操作(当a的容量不足时电脑会自动扩容,当然这必然降低性能) 

a.swap(b); // b 为向量,将向量  a 与向量 b 进行替换,其内存大小等所有的性质都会相应变化
a == b; // 向量 a 与 向量 b进行比较,还有 >= <= != > 等

4. 使用sort()函数对vector进行排序

  • 首先需要头文件:
#include 
using namespace std;
  • sort(start, end, cmp)函数接收2个或3个参数, 第一个参数 start 是要排序的区间首地址,第二个参数 end 是排序区间的尾地址,即左闭右开,第三个参数 cmp 是排序函数,默认是升序
    排序函数 cmp可以自定义,返回值为bool型,它定义了什么样的关系才是“小于”;
  • 按照降序
bool cmp(int a, int b)
{
   return a>b;
}
sort(a.begin(), a.end(), cmp);
  • 多种排序规则, 有一个node类型的数组node arr[100]先按 x 值升序排列,如果 x 值相同,再按 y 值降序排列,如果 z 还相同,就按 z 降序排列。就可以写这样一个比较函数:
struct node
{
  int x;
  int y;
  int z;
};

bool cmp(node k1, node k2)
{
  if(k1.x != k2.x)
    return k1.x < k2.x;
  if(k1.y != k2.y)
    return k1.y > k2.y;
  if(k1.z != k2.z)
    return k1.z > k2.z;
}
sort(a.begin(), a.end(), cmp);
-----------------------------------------------------------------------------------------
//重构<
bool operator<(const node& k1, const node& k2)
{
  return k1.x > k2.x;
}
sort(a.begin(), a.end()); // 按照 k1.x降序
a.begin(); // 返回向量 a 的第一个元素的地址
a.end(); // 返回向量 a 的最后一个元素的地址
sort(a.rbegin(), a.rend()); // 升序
------------------------------------------------------------------------------
a.rbegin();  // 返回向量 a 的逆序第一个元素的地址,即最后一个地址
a.rend(); // 返回向量 a 的逆序最后一个元素的地址,即第一个地址
sort(a.rbegin(), a.rend()); // 可以将默认的升序变成降序

你可能感兴趣的:(vector 的用法——2018-08-30)