欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

向量 vector

程序员文章站 2022-03-23 13:28:36
...

向量(vector)可以看成是“动态数组”,即可以保存的元素个数是可变的。

与数组相比,使用向量时要注意:向量的大小是可变的。开始时向量为空,随着不断插入元素,向量自动申请空间,容量变大。

vector动态增长基本原理:当插入新元素的时候,如果空间不足,那么vector会重新申请更大的一块内存空间,将原空间数据拷贝到新空间,释放旧空间,再把新元素插入到新申请空间。

一、定义

1、定义vector:

vector<typename> name;  //typename可以是任何基本类型,也可以是STL容器
vector<vector<typename> > name;  //c++11之前会将>>视为移位操作,所以要加空格> >

2、定义vector数组:

vector<typename> Arrayname[arraySize]; 
//与vector<vector<typename> >不同的是,一维已经固定长度为arraySize

二、vector的初始化

vector有4种方式初始化,有直接初始化,也要通过拷贝构造函数初始化。

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

    //直接构造函数初始化
    vector<int> v1;
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);
    
    //通过拷贝构造函数初始化
    vector<int> v2 = v1;
    
    //使用部分元素来构造
    vector<int> v3(v1.begin(), v1.begin() + 1);
    vector<int> v4(v1.begin(), v1.end());
    
    //存放三个元素,每个元素都是9
    vector<int> v5(3,9);
    
    int arr[] = {2,3,6,7};
    vector<int> v5(arr, arr + sizeof(arr)/sizeof(int));
    
    return 0;
}

三、vector的赋值

vector<int> v;
v.assign(5,1);

vector<int> v1;
v1.assign(v.begin(), v.end());

vector<int> v2;
v2 = v1;

四、vector的添加和删除

既然vector是容器,那么就可以向这个容器添加删除元素。

基本用法:

  • front() 返回头部元素的引用,可以当左值

  • back() 返回尾部元素的引用,可以当左值

  • begin() 向量的第一个元素的位置,返回第一个元素迭代器

  • end() 向量的结束位置。注意,返回的迭代器是最后一个元素的后面位置,不是最后一个元素的迭代器

  • push_back()添加元素,只能尾部添加

  • pop_back()移除元素,只能在尾部移除

int main(int argc, const char * argv[]) {
    
    //定义一个vector容器
    vector<int> v1;
    
    //插入元素(尾部插入)
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    
    //迭代器遍历打印
    for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    
    //修改头部元素的值(front()返回是引用,可以当左值)
    v1.front() = 44;
    
    //输出头部元素
    cout<< "头部元素:" << v1.front() << endl;
    
    //修改尾部的值(back()返回是引用,可以当左值)
    v1.back() = 99;
    
    //输出尾部元素
    cout << "尾部元素" << v1.back() <<endl;
    
    //删除元素(从尾部删除)
    v1.pop_back();
    
    //迭代器遍历打印
    for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    
    return 0;
}

五、vector的push_back强化

push_back是在当前vector的内存末尾拷贝元素进入容器。注意这个地方可能产生浅拷贝,所以容器中的对象要支持拷贝操作。另外,如果vector初始化了个数,而不初始化具体的值,push_back也只会在最后面追加。

int main(int argc, const char * argv[]) {
    
    //初始化10个元素的容器
    vector<int> v(10);
    
    //打印容器大小
    cout << v.size() << endl;
    
    //push_back添加元素
    v.push_back(100);
    
    //打印容器大小
    cout << v.size() << endl;
    
    //遍历后的结果是  0 0 0 0 0 0 0 0 0 0 100
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    
    return 0;
}

六、vector的插入元素

vector在尾部添加或者移除元素非常快,在中间操作非常耗时,因为它需要移动元素

vector提供了insert函数,结合迭代器位置插入指定的元素。如果迭代器位置越界,会抛出异常。

insert() 函数有3种用法:
第1种语法:
iterator insert( iterator loc, const TYPE &val );
参数的含义:在指定位置loc前插人值为val的元素,返回指向这个元素的选代器。

第2种语法:
void insert( iterator loc, size_ type num, const TYPE &val );
参数的含义:在指定位置loc前插人num个值为val的元素。

第3种语法:
void insert( iterator loc, input iterator start, input_ iterator end );
参数的含义:在指定位置loc前插人区间 [start, end] 的所有元素。

int main(int argc, const char * argv[]) {
    
    //初始化vector对象
    vector<int> v1(10);
    
    //在指定的位置插入元素10的拷贝
    v1.insert(v1.begin() + 3, 10);
    
    //在指定的位置插入3个元素11的拷贝
    v1.insert(v1.begin(), 3, 11);
    
    //遍历
    for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    
    return 0;
}

七、vector的删除元素

vector的删除,是根据位置进行删除,如果想要删除某个元素,需要找到当前元素的迭代器位置,再进行删除。

erase(iterator)函数,删除后会返回当前迭代器的下一个位置。

int main(int argc, const char * argv[]) {
    
    //1 创建容器并初始化
    vector<int> v1(10);
    for (int i = 0; i < v1.size(); i++) {
        v1[i] = i;
    }
    
    //2 区间删除
    //--2.1 删除前3个元素
    v1.erase(v1.begin(), v1.begin() + 3);
    
    //--2.2 删除指定位置的元素
    v1.erase(v1.begin() +3);
    
    //3 根据元素的值进行删除,删除值为2的元素
    v1.push_back(2);
    v1.push_back(2);
    vector<int>::iterator it = v1.begin();
    while (it != v1.end()) {
        if (*it == 2) {
            it = v1.erase(it);   //删除后,迭代器指针会执行下一个位置并返回。
        }else{
            it++;
        }
    }
    
    //4 遍历打印
    for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    
    return 0;
}

八、vector的访问

vector容器可以随机存取元素,也就是说支持[]运算符和at方式存取。

vector的遍历有多种方式,可以根据[]或者迭代器遍历。需要注意的是:

  • []方式,如果越界或出现其他错误,不会抛出异常,可能会崩溃,可能数据随机出现
  • at方式,如果越界或出现其他错误,会抛出异常,需要捕获异常并处理
  • 迭代器提供了逆向遍历,可以通过迭代器来实现逆向遍历,当然上面两种方式也可以
int main(int argc, const char * argv[]) {
    
    //创建vector
    vector<int> v1;
    
    //插入元素
    for (int i = 0; i < 10; i++) {
        v1.push_back(i);
    }
    
    //遍历-[]取值
    for (int i = 0; i < v1.size(); i++) {
        cout << v1[i] << " ";
    }
    cout << endl;
   
    //遍历-at取值
    for (int i = 0; i < v1.size(); i++) {
        cout << v1.at(i) << " ";
    }
    cout << endl;

    //遍历-迭代器遍历
    for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    
    //遍历-迭代器逆向遍历
    for (vector<int>::reverse_iterator it = v1.rbegin(); it != v1.rend(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    
    //测试越界
    cout << "[]越界:" << v1[20] << endl;      //不会抛出异常,可能会崩溃,可能会乱码
    cout << "at越界:" << v1.at(20) << endl;   //会抛出异常,需要捕获异常
    
    return 0;
}

九、vector总结

  1. 访问vector信息
    访问vector信息的函数有max_size、 size()、 capacity() 和 empty()。
    max_size 返回 vector 可以最多容纳元素的数量;
    size() 返回 vector 当前元素的数量;
    resize() 重新设定向量的大小,即可以保存多少个元素
    capacity() 返回 vector 所能容纳的元素数量(在不重新分配内存的情况下);
    empty() 判断vector 是否为空,为空时返回TRUE,否则返回FALSE。
    clear() 清除向量所有的元素,size变为0
  2. 存储vector信息
    存储vector信息可以使用构造函数、push_back()、insert()、数组运算符、赋值运算符、pop_back()、erase()、begin()、 end()、rbegin()、 rend()、 size、 maxsize 等。