vector的常用方法总结

 注意:使用下列代码请include必要头文件

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
初始化和赋值方式
int main(){
    //(1)初始化方式
    // 列表初始化
    vector<int> arr{1,2,3}; //arr={1,2,3}
    //指定大小和初始值
    vector<int> arr2(3,0); //arr2={0,0,0}
    vector<vector<int>> arr_2d(2, vector<int>(3,0)); //二维向量arr_2d={{0,0,0},{0,0,0}}
    
    //从其他向量中拷贝指定范围的元素
    vector<int> arr3(arr.begin(), arr.end()); //arr3={1,2,3}

    //(2) 给vector赋值
    // 使用构造函数
    vector<int> arr_c1 = arr; //arr_c1={1,2,3}
    arr_c1 = {4,5,6}; //arr_c1={4,5,6}

    return 0;
}
访问元素
int main(){
    vector<int> arr{1,2,3,4,5,6,7};
    //1、根据下标访问元素
    arr[3]; //arr[3]=4
    //2、根据迭代器访问元素
    auto it = arr.begin(); //it->1 *it=1
    it++; //it->2
    it = arr.end(); //it指向vector末尾的随机访问迭代器
    auto it_r = arr.rbegin(); //it->7
    it_r = it_r + 2; //it->5
    it_r = arr.rend(); //it指向反向矢量末尾的迭代器
    return 0;
}
增-添加元素
int main(){
    vector<int> arr{1,2,3};
    //1、在尾部插入元素--介绍push_back和emplace_back
    arr.push_back(4); //arr={1,2,3,4}
    //或在尾部就地插入元素
    arr.emplace_back(5); //arr={1,2,3,4,5}

    //2、在指定位置插入元素--介绍insert
    auto it_pos = arr.begin() + 2;
    arr.insert(it_pos, 6); //arr={1,2,6,3,4,5}
    //在指定位置批量插入元素
    //如在it_pos位置处插入2个7
    arr.insert(it_pos, 2, 7); //arr={1,2,7,7,6,3,4,5}
    
    return 0;
}

这里解释下什么是就地构造元素,和普通添加元素有什么区别。

push_backemplace_back方法为例,同样是将元素插入末尾。当我们需要在末尾插入一个临时元素时,使用push_back会先构造一个临时对象,然后再将这个元素的值拷贝或移动进元素末尾;而emplace_back会在容器末尾直接构造一个元素,不会进行多余的拷贝或移动。见下列代码

class A
{
public:
    A(int n){
        cout << "A structure" << endl;
    }
    A(const A& a){
        cout << "A copy structure" << endl;
    }
    A(A&& a){
        cout << "A move structure" << endl;
    }
private:
};

int main(){
    vector<A> arr1, arr2;
    cout << " push back:" << endl;
    arr1.push_back(1);
    cout << " emplace back:" << endl;
    arr2.emplace_back(1);

    return 0;
}

输出结果

可见,当我们需要在容器中添加一个新元素,并且可以通过构造函数的参数列表直接在容器中构造对象时,使用emplace_back是更为高效的选择。

但是我们如果想在元素末尾插入一个已经存在的对象时,使用puch_back和emplace_backd的表现都是一样的,都是会直接调用对象拷贝或移动构造函数来插入元素。见下代码

A a1(1), a2(2);
vector<A> arr1, arr2;
cout << " push back:" << endl;
arr1.push_back(a1);
cout << " emplace back:" << endl;
arr2.emplace_back(a2);

输出:

A a1(1), a2(2);
vector<A> arr1, arr2;
cout << " push back:" << endl;
arr1.push_back(std::move(a1));
cout << " emplace back:" << endl;
arr2.emplace_back(std::move(a2));

输出:

所以,当需要插入一个已经存在的对象,使用push_back可能更简洁合适。

删除元素
int main(){
    vector<int> arr{1,2,3,4,5,6,7};
    //1、在尾部删除元素--介绍pop_back
    arr.pop_back(); //arr={1,2,3,4,5,6}

    //2、删除指定位置元素--介绍erase
    auto it_pos = arr.begin() + 2;
    //删除第3个元素,并返回了删除的后一个元素的迭代器
    it_pos = arr.erase(it_pos); //arr={1,2,4,5,6}, it_pos->4

    //3、批量删除元素
    it_pos = arr.erase(it_pos, it_pos+2); //arr={1,2,6}, it_pos->6

    //4、批量删除某元素--介绍遍历和使用remove函数
    // (1)批量删除元素可以在遍历过程中使用erase逐个删除,比如删除arr2中的元素2
    vector<int> arr2{1,2,3,4,2,5,7,6,7,2,5,8};
    auto it2 = arr2.begin();
    while(it2 != arr2.end())
    {
        if(*it2 == 2)
            it2 = arr2.erase(it2);
        else
            ++it2;
    }
    //结束后arr2={1,3,4,5,7,6,7,5,8}

    //(2)使用remove函数
    //remove可以从给定范围中删除指定值,而不影响剩余元素的顺序。返回没有指定值的新范围的结束位置。
    //需要注意的是,remove处理过后的容器并没有完全将所需数值删除,而是移到了最后,结合remove的返回值(新范围的结束位置)将容器分成了“有效部分”和“无效部分”。需要使用earse删除无效部分。
    auto it_new_end = std::remove(arr2.begin(), arr2.end(), 7);
    //运行后发现arr2={1 3 4 5 6 5 8 5 8}还是9个元素,it_new_end指向arr2[7]

    //需要根据返回的新最后位置,使用erase删除无效元素
    arr2.erase(it_new_end, arr2.end()); //arr2={1 3 4 5 6 5 8}

    //(3)根据条件批量删除元素--介绍remove_if
    // remove_if需要传入一个条件谓词,可以使用匿名函数表达条件,返回值为bool,true代表条件满足(需要移除)
    // remove_if的其他参数和返回值用法同remove
    // 例题:删除数组中的奇数
    arr2.erase(remove_if(arr2.begin(),arr2.end(),
                         [](int val){return val%2 != 0;}),
               arr2.end());
    // arr2={4 6 8}

    return 0;
}
查找元素

vector类不带有查找某元素的成员方法,我们可以使用 algorithm 中的方法。 

int main(){
    vector<int> arr{1,2,3,4,5,6,7};
    //1、查找某元素--介绍find(起始位置迭代器,结束位置迭代器,数值)
    // 查找到-返回指向第一次出现该元素的迭代器
    auto it = find(arr.begin(), arr.end(), 5); //it->5
    // 查找某元素位置下标
    int pos = distance(arr.begin(), it); // pos=4
    // 没有查找到-返回find输入的结束位置迭代器
    it = find(arr.begin(), arr.end(), 9); //arr中没有元素9 it=arr.end()

    // 2、条件查找--介绍find_if(起始位置迭代器,结束位置迭代器,条件)
    // 条件可以使用匿名函数,确保函数返回值为bool类型,true代表找到,返回指定迭代器;false代表未找到,返回结束位置迭代器
    // 例如,查找第一个偶数
    it = find_if(arr.begin(), arr.end(),
                 [](int val){return val%2==0;}); //it->2

    return 0;
}
替换元素
int main(){
    vector<int> arr{3,4,3,5,7};
    //(1)替换指定元素
    //例:将3替换成6
    replace(arr.begin(), arr.end(),3,6); //arr={6,4,6,5,7}
    //(2)按照条件替换
    //例:将所有偶数替换成0
    replace_if(arr.begin(), arr.end(),
               [](int v){return v%2==0;}, 0);//arr={0,0,0,5,7}

    return 0;
}
其他常用算法
int main(){
    vector<int> arr{1,3,4,5,2};
    //(1)求容器大小
    int si = arr.size(); //si=5

    //(2)反转容器中的元素
    reverse(arr.begin(), arr.end()); //arr={2,5,4,3,1}

    //(3)求元素最大值、最小值
    auto it_max = max_element(arr.begin(), arr.end()); //it_max->5
    auto it_min = min_element(arr.begin(), arr.end()); //it_min->1

    //(4)交换容器中两个元素
    swap(arr[2],arr[4]); //arr={2,5,1,3,4}
    
    //(5)排序
    //按照升序排列
    sort(arr.begin(), arr.end()); //arr={1,2,3,4,5}
    //按照降序排列
    sort(arr.begin(),arr.end(),std::greater<int>()); //arr={5,4,3,2,1}
    //std::greater<int>()是一个函数对象,是std::greater模版类的int特化,用于比较两个函数的大小关系,按照降序比较
    //相对的,std::less<int>()是按照升序比较。sort函数默认是升序的

    return 0;
}

【参考资料】

vector 类 | Microsoft Lea

<algorithm> | Microsoft Learn

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值