首页 热点 正文

CF竞赛必备,C++动态数组(vector)赋值全攻略

热点 181
在CF竞赛中,C++动态数组vector是高效处理数据的必备工具,掌握其赋值方法对提升解题效率至关重要,常见赋值方式丰富多样:初始化时可直接用列表赋值,如vector v={1,2,3};通过push_back()逐个添加元素,适配动态输入场景;assign()方法可批量设定元素值或拷贝其他容器元素;还能通过拷贝构造或赋值运算符直接复制已有vector;emplace_back()则能原地构造元素,比push_back更高效,竞赛中需根据数据规模和场景选择合适方法,兼顾速度与内存优化,助力快速实现解题逻辑。

在Codeforces(CF)算法竞赛中,C++的vector作为动态数组的核心实现,是处理可变长度数据的必备工具,熟练掌握动态数组的赋值技巧,不仅能提升代码编写效率,还能避免常见的运行时错误,本文将从基础到进阶,结合竞赛场景全面解析vector的赋值方法。

基础初始化赋值:从固定数据到默认填充

列表初始化:直观定义已知元素

当你明确知道动态数组的初始元素时,列表初始化是最简洁的方式,这种方法适合小规模固定数据的场景,比如竞赛中初始化测试用例或预设值:

CF竞赛必备,C++动态数组(vector)赋值全攻略

#include <vector>
using namespace std;
int main() {
    // 初始化包含1、3、5、7的动态数组
    vector<int> nums = {1, 3, 5, 7};
    return 0;
}

指定大小与默认值:批量初始化避免垃圾值

竞赛中常需要创建固定大小且元素统一的数组(如全0数组),此时可以通过构造函数直接指定大小和默认值,避免手动循环赋值:

// 创建包含10个元素的数组,每个元素初始化为0
vector<int> nums(10, 0);
// 创建包含5个字符串的数组,每个元素为"CF"
vector<string> strs(5, "CF");

直接赋值与拷贝:复用已有数据

整体拷贝赋值:快速复制整个数组

如果你需要复用另一个动态数组的所有元素,可以直接用赋值运算符完成拷贝,生成一个完全独立的副本:

vector<int> old_nums = {2, 4, 6};
// 拷贝old_nums的所有元素到new_nums
vector<int> new_nums = old_nums;

assign方法:灵活批量赋值

assign方法比直接赋值更灵活,支持三种赋值方式:

  • 按元素个数+默认值赋值:
    vector<int> nums;
    // 赋值5个元素,每个元素为1
    nums.assign(5, 1);
  • 按迭代器范围拷贝(适合部分复制):
    vector<int> old_nums = {1,2,3,4,5};
    vector<int> new_nums;
    // 拷贝old_nums中第2到第4个元素(左闭右开)
    new_nums.assign(old_nums.begin()+1, old_nums.end()-1);

遍历输入赋值:竞赛高频场景

竞赛中最常见的需求是读取用户输入并赋值给动态数组,这里有两种高效方式:

push_back逐个添加:未知数据量首选

当你不确定输入数据的数量(或数据量较小)时,用push_back动态添加元素是最稳妥的选择:

#include <iostream>
#include <vector>
using namespace std;
int main() {
    int n;
    cin >> n;
    vector<int> nums;
    // 读取n个整数并添加到数组
    for (int i = 0; i < n; ++i) {
        int x;
        cin >> x;
        nums.push_back(x);
    }
    return 0;
}

resize后下标赋值:已知数据量更高效

如果提前知道输入数据的数量,先通过resize固定数组大小,再用下标直接赋值,避免push_back的自动扩容开销,适合大数据量场景:

int n;
cin >> n;
vector<int> nums(n); // 提前分配n个元素的空间
for (int i = 0; i < n; ++i) {
    cin >> nums[i]; // 直接通过下标赋值
}

高效赋值进阶技巧:优化竞赛性能

emplace_back替代push_back:减少拷贝开销

emplace_back直接在数组末尾构造元素,避免了push_back可能产生的拷贝或移动操作,在处理自定义类型或大数据时效率更高:

// 直接构造整数10并添加到数组,无需临时拷贝
nums.emplace_back(10);

fill批量填充:快速重置数组元素

如果需要将数组所有元素统一设置为某个值,使用algorithm库中的fill函数比手动循环更简洁高效:

#include <algorithm>
// 将nums中所有元素设置为0
fill(nums.begin(), nums.end(), 0);

从其他容器赋值:兼容数组、列表等

vector支持从普通数组、list等容器赋值,只需传入迭代器范围:

// 从普通数组赋值
int arr[] = {1,2,3};
vector<int> nums(arr, arr + 3);
// 从list赋值
list<int> l = {4,5,6};
nums.assign(l.begin(), l.end());

常见误区与注意事项

  1. 避免未初始化直接用下标:未添加元素的vector为空,直接用nums[0] = 1会触发越界错误,必须先resizepush_back元素后才能使用下标。
  2. 提前reserve减少扩容:频繁push_back会触发自动扩容(每次扩容通常翻倍),若已知数据量,提前用nums.reserve(n)预留空间,可减少内存分配次数,提升性能。
  3. 区分resizereserveresize会改变数组大小并初始化元素,reserve仅预留空间,不改变数组实际大小。

在CF竞赛中,动态数组的赋值没有“最优解”,只有“最适合场景的解”:初始化用列表或指定大小,输入用push_backresize下标,拷贝用assign,高效赋值用emplace_backfill,掌握这些技巧,能让你的代码更简洁、高效,轻松应对竞赛中的各种数据处理需求。

版权声明 本文地址:https://www.tcs2545.cn/12397.html
1.文章若无特殊说明,均属本站原创,若转载文章请于作者联系。
2.本站除部分作品系原创外,其余均来自网络或其它渠道,本站保留其原作者的著作权!如有侵权,请与站长联系!
扫码二维码