加载中...

信息奥赛|STL|vector


信息奥赛|STL|vector

vector 简介 🚀

vector 是标准模板库(STL)中的一种 动态数组 容器,存储同一种特定类型的元素。

vector 支持通过索引进行快速随机访问元素,随机存取任何元素都能在常数时间完成,在尾端增删元素时具有较佳的性能。


vector 详解 ☘️

vector 头文件

#include <vector>  

🍉PS:竞赛中建议直接使用万能头文件 #include<bits/stdc++.h>

vector 初始化

vector<int> v;  //初始化vector v
vector<int>::iterator it;  //初始化vector的迭代器 it

vector<int> v[5];  //初始化一个二维的vector

vector 添加元素

for (int i = 0; i < n; ++i) {
    cin >> tmp;
    v.push_back(tmp);  //vector通过push_back()的方式,向尾部添加元素
}

vector 元素访问

单个元素访问

  • 访问首部元素

    cout << "首部元素为:" << v.front() << endl;   //v.front()返回首部元素值
    cout << "首部元素为:" << *v.begin() << endl;  //v.begin()返回首部元素地址
    cout << "首部元素为:" << v[0] << endl;        //vector支持下标随机访问
  • 访问第 k(1<=k<=v.size())个元素

    cout << "第k个元素为:" << *(v.begin() + k - 1) << endl;
    cout << "第k个元素为:" << v[k - 1] << endl;

    🍉PS:vector 支持 随机访问(仅有 vectorstring 支持随机访问),可以用 (it + k) 的方式改变迭代器的值;其他容器不支持随机访问,仅能用 it++/it-- 的方式改变迭代器的值

  • 访问末尾元素

    cout << "末尾元素为:" << *(--v.end()) << endl;  //v.end()返回末尾元素的后一个位置
    cout << "末尾元素为:" << v[v.size() - 1] << endl; //v的下标范围是[0,v.size()-1]

    🍉PS1:vector 没有 v.back() 方法来访问末尾元素;但是有 v.front() 方法来访问首部元素

    🍉PS2:vector 中的 end() 方法返回的是末尾元素的下一个位置的地址,故 --v.end() 返回末尾元素的地址,*(--v.end()) 返回末尾元素值。(🤔思考:*(v.end()--) 能否输出末尾元素的值)

整体元素遍历

  • 迭代器遍历

    for (it = v.begin(); it != v.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
  • 下标法遍历

    for (int i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;
  • 智能指针遍历(熟练后推荐)

    for (auto t: v) {
        cout << t << " ";
    }
    cout << endl;

vector 元素查找(不推荐)

vector 可以通过使用 find() 函数来查找某个元素,若找到,则返回当前元素的迭代器;若找不到,返回 v.end()

find() 函数查找 vector 中元素的时间复杂度为 $O(N)$ 。(不推荐 😵‍💫)

set、map 等容器自带 find() 方法,查找的时间复杂度仅为 $O(logN)$ (推荐 ✅)

it = find(v.begin(), v.end(), tmp);
if (it != v.end()) {   
    cout << "当前vector中存在该元素" << endl;
} else {
    cout << "当前vector中不存在该元素" << endl;
}

vector 排序

元素为 int 类型

  • 升序

    sort(v.begin(),v.end());
  • 降序

    • 使用 greater<int>()

      sort(v.begin(),v.end(),greater<int>());
    • 自定义排序参数 cmp

      bool cmp(int a,int b){   //定义cmp参数,比较int类型
        return a>b;
      }
      sort(v.begin(),v,end(),cmp);

🍉PS:当元素为结构体时,直接定义结构体数组,然后用 sort() 对结构体数组排序即可。

vector 反转

reverse(v.begin(), v.end()) //使用reverse函数反转当前vector

vector 常用方法函数

常用方法函数概览

方法 功能描述 时间复杂符
v.push_back(element) 在末尾添加一个元素 $O(1)$
v.pop_back() 删除末尾元素 $O(1)$
v.front() 返回第一个元素值 $O(1)$
v.size() 返回当前 vector 中元素数量 $O(1)$
v.begin() 返回首元素的迭代器(地址) $O(1)$
v.end() 返回 末尾元素后一个位置 的迭代器(地址) $O(1)$
v.clear() 清空当前 vector $O(N)$
v.empty() 判断当前 vector 是否为空,为空返回真,反之返回假 $O(1)$
v.erase(it + k -1) 删除第 k 个元素,it = v.begin() /

部分常用方法函数详解

v.push_back(element)

v.push_back(100);  //将元素100插入vector末尾

v.pop_back()

v.pop_back();  //删除当前末尾元素

v.begin() / v.end()

vector<int>::iterator it;
for(it = v.begin();it!=v.end();it++){  //经常用于遍历vector
	cout<<*it<<" "
}
cout<<endl;

v.empty()

if(!v.empty()) ...  //如果当前vector非空

v.clear()

v.clear();  //清空当前vector

🍉 PS:容器和容器适配器不同, stack,queue 等容器适配器不支持 clear() 方法,只能用 逐个出栈/队 的方式清空。


vector OI 案例 🧑🏻‍💻

OI 案例1

【题目描述】

实现一个线性表: 参照 sq_delete 函数,对一个 $n$ 不超过 $1024$ 的线性表进行删除操作。

【输入】

第一行有一个整数 $n$,表示线性表的大小,第二行有 $n$ 个整数,分别是 list1, list2 … listn 。
第三行有一个整数 $q$,表示 $q$ 次删除操作,接下来 $q$ 行,每行有一个整数 $k$,表示删除线性表中第 $k$ 个元素。
(输入有多组测试数据,以 EOF 结束)

【输出】

对于每次删除操作输出一行,如果 $k$ 不合法,输出 $-1$, 否则输出删除的元素。

【输入样例】
5 
3 2 1 5 4 
3 
5 
5 
2
【输出样例】
4 
-1 
2

【题目分析】

本题使用 STL 容器,可以很大程度上简化代码。

【C++ 代码】
#include<bits/stdc++.h>

using namespace std;
int n, q, tmp, id;
vector<int> v;
vector<int>::iterator it;

int main() {
    while (cin >> n) {
        v.clear();    //题目有多组样例,必须添加本行代码清空上一个v,否则会出错
        for (int i = 0; i < n; ++i) {
            cin >> tmp;
            v.push_back(tmp);
        }

        cin >> q;
        while (q--) {
            cin >> id;
            if (id < 1 || id > v.size()) {
                cout << -1 << endl;
            } else {
                it = v.begin();
                cout << *(it + id - 1)<<endl;   //vector 支持随机访问
                v.erase(it + id - 1);
            }
        }
    }
    return 0;
}

文章作者: Rickyの水果摊
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Rickyの水果摊 !
  目录