容器库(2)-std::vector

本文围绕C++的std::vector展开,它管理动态分配的数组,可在运行时增删元素。详细介绍了其成员函数,包括构造、赋值、析构、元素访问、迭代器、容量和修改器等,还介绍了非成员函数,如比较运算符、std::swap等,并给出各函数代码示例及输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

std::vector管理的是动态分配的数组,可以在运行时添加和删除元素。vector管理的底层内存是连续的,当添加元素时没有剩余容量时,vector会重新申请一片新的合适大小的连续内存。

本文章的代码库:

https://gitee.com/gamestorm577/CppStd

成员函数

构造、赋值和析构

构造函数

可以用元素或者另一个vector来构造vector。代码示例:

std::vector<float> v1;
std::vector<float> v2(3, 1.f);
std::vector<float> v3(3);
std::vector<float> v4(v2.begin(), v2.begin() + 2);
std::vector<float> v5(v2);
std::vector<float> tmp(v2);
std::vector<float> v6(std::move(tmp));
std::vector<float> v7{1.f, 2.f, 3.f, 4.f, 5.f};

std::cout << "v1 size = " << v1.size() << std::endl;
std::cout << "v2 size = " << v2.size() << std::endl;
std::cout << "v3 size = " << v3.size() << std::endl;
std::cout << "v4 size = " << v4.size() << std::endl;
std::cout << "v5 size = " << v5.size() << std::endl;
std::cout << "v6 size = " << v6.size() << std::endl;
std::cout << "v7 size = " << v7.size() << std::endl;

输出结果:

v1 size = 0
v2 size = 3
v3 size = 3
v4 size = 2
v5 size = 3
v6 size = 3
v7 size = 5

析构函数

销毁vector时,会从右到左依次调用元素的析构函数。代码示例:

struct MyStruct
{
    ~MyStruct()
    {
        std::cout << "Destruct " << Index << std::endl;
    }

    int Index = 0;
};

std::vector<MyStruct> vec(3);
vec[0].Index = 1;
vec[1].Index = 2;
vec[2].Index = 3;

输出结果:

Destruct 3
Destruct 2
Destruct 1

赋值函数

可以另一个vector或者元素列表给vector赋值。代码示例:

std::vector<int> tmp{1, 2, 3, 4};
std::vector<int> vec1;
std::vector<int> vec2;
std::vector<int> vec3;

vec1 = tmp;
vec2 = std::move(tmp);
vec3 = {1, 2, 3, 4, 5};
std::cout << "vec1 size = " << vec1.size() << std::endl;
std::cout << "vec2 size = " << vec2.size() << std::endl;
std::cout << "vec3 size = " << vec3.size() << std::endl;

输出结果:

vec1 size = 4
vec2 size = 4
vec3 size = 5

assign

可以用元素、元素列表和迭代器给vector赋值,vector原来的内容将被替换。代码示例:

std::vector<float> vec = {1.f, 2.f, 3.f, 4.f, 5.f};
std::vector<float> tmp = {1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f};

vec.assign(3, 5.f);
std::cout << "vec size = " << vec.size() << std::endl;
vec.assign(tmp.begin(), tmp.begin() + 7);
std::cout << "vec size = " << vec.size() << std::endl;
vec.assign({1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f});
std::cout << "vec size = " << vec.size() << std::endl;

输出结果:

vec size = 3
vec size = 7
vec size = 8</
<think>好的,我现在需要解决用户的问题:如何用C++ STL计算两个std::vector<std::set<int>>容器内对应位置集合的交集和差集,并将结果存入新容器。首先,我需要理清用户的需求。用户有两个vector,每个元素都是set<int>,他们希望逐一对每个对应的set进行交集和差集操作,然后将结果保存到新的vector中。 首先,我得确认用户的数据结构。两个vector的每个元素都是set<int>,并且是按位置对应的,也就是说第一个vector的第i个set和第二个vector的第i个set进行操作。这要求两个vector的大小必须相同,否则会出问题。不过用户可能已经确保这一点,或者需要代码中做检查,但用户的问题中没有提到,可能需要考虑,但暂时先假设大小相同。 接下来,如何逐个处理对应的set。对于每个位置i,取vector1[i]和vector2[i]的set,计算它们的交集和差集。差集可能有不同的方向,比如A-B或B-A,用户需要哪一种?用户的问题中没有明确说明,可能需要同时处理两种差集,或者只处理一种。根据引用[3]中的内容,差集的方向取决于参数的顺序,所以可能需要用户指定,但根据问题描述,用户可能希望得到两个容器对应位置的差集,可能是指每个元素各自的差集,比如A-B和B-A,或者只是其中一种。不过用户的问题里提到“差集”,可能需要明确。但根据用户提供的引用,特别是引用[3]中的例子,如果要求A-B,就是set_difference(a.begin(), a.end(), b.begin(), b.end(), ...),而B-A则是交换参数位置。所以可能需要用户明确差集的方向,但问题中可能希望得到两个差集结果吗?或者只其中一个? 不过用户的问题中,他说“交集与差集”,可能希望每个对应的位置得到一个交集和一个差集的结果,例如,每个元素得到一个交集的结果集和一个差集的结果集。因此,可能需要生成两个新的vector<set<int>>,一个存放所有交集,另一个存放所有差集。或者,用户可能希望将交集和差集都存入同一个结构,但根据问题描述,更可能是分别存储。 现在,如何用STL算法来实现这一点。根据引用[1]、[2]、[3],特别是引用[3]中提到的set_intersection和set_difference函数,这些函数用于两个有序集合的交集和差集计算。因为set本身是有序的,所以可以直接使用这些算法。 具体步骤应该是: 1. 确保两个vector的大小相同,否则无法对应处理。 2. 创建两个新的vector<set<int>>,分别用于存储交集和差集的结果。 3. 遍历两个输入vector的每个对应位置的set。 4. 对每对set,使用std::set_intersection计算交集,并插入到交集的vector中。 5. 同样,使用std::set_difference计算差集(比如A-B),并插入到差集的vector中。 6. 返回这两个新的vector作为结果。 需要注意的是,std::set_intersection和std::set_difference需要目标容器使用插入迭代器,比如std::back_inserter或者直接插入到set中。然而,set的插入可能需要使用inserter,因为set的back_inserter可能不适用,因为set没有push_back方法。但在这里,每个结果是一个set<int>,所以对于每个位置i的交集,应该创建一个新的set<int>,然后使用std::inserter来填充这个set。 例如,对于两个set<int> a和b,交集可以这样计算: std::set<int> intersect; std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::inserter(intersect, intersect.begin())); 同理,差集: std::set<int> diff; std::set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(diff, diff.begin())); 然后,将intersect和diff分别添加到结果vector中。 现在,针对两个vector<set<int>>的操作,需要遍历每个元素,并执行上述操作。因此,代码的大致结构可能是这样的: std::vector<std::set<int>> vec1, vec2; // 假设vec1和vec2已经初始化,并且大小相同 std::vector<std::set<int>> intersections; std::vector<std::set<int>> differences; for (size_t i = 0; i < vec1.size(); ++i) { const auto& set1 = vec1[i]; const auto& set2 = vec2[i]; std::set<int> intersect; std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), std::inserter(intersect, intersect.begin())); std::set<int> diff; std::set_difference(set1.begin(), set1.end(), set2.begin(), set2.end(), std::inserter(diff, diff.begin())); intersections.push_back(intersect); differences.push_back(diff); } 这样,intersections和differences分别保存了每个对应位置集合的交集和差集(A-B)。 需要注意的是,std::set_intersection和std::set_difference要求输入的范围是有序的,而std::set本身是有序的,所以这里没问题。此外,结果集需要用inserter来插入元素,因为set的迭代器是const的,不能直接写入。 用户的问题中还提到,结果需要存入新容器,也就是这两个新的vector。 另外,是否需要处理vec1和vec2的大小不一致的情况?在代码中,可能需要先检查两个vector的大小是否相同,否则循环会越界。所以,在代码中应该添加一个assert或者条件判断,比如: assert(vec1.size() == vec2.size()); 或者在循环前检查,如果大小不同,抛出异常或处理错误。但用户的问题中没有提到这一点,可能默认假设两个vector大小相同。 综上,这个代码应该可以解决问题。同时,如果用户需要不同的差集方向(比如B-A),可以再创建一个循环来存储另一个方向的差集。 另外,用户可能希望将交集和差集的结果分别存入两个新的vector<set<int>>中,正如上面的代码所做的。 现在,根据用户提供的引用,特别是引用[3]中的例子,使用std::set_difference时参数的顺序决定了差集的方向。因此,用户如果希望得到A-B和B-A两种差集,需要分别调用两次,并存储到不同的vector中。但用户的问题中只提到差集,可能需要明确是哪种方向,但根据问题描述,可能只需要一个方向的差集。因此,在回答时需要说明这一点,或者给出示例代码处理一种或两种差集。 现在,我需要将上述思考整理成一个结构化的回答,确保符合用户的要求,包括使用正确的中文,代码格式正确,引用相关引用内容。 例如,在回答中可以提到使用std::set_intersection和std::set_difference函数,遍历vector的每个元素,使用std::inserter将结果插入到新set中,然后将这些set添加到结果vector中。同时,可以引用引用[3]中的内容,说明差集的方向由参数的顺序决定。 此外,引用[1]中提到的使用STL算法函数来处理集合操作,这里同样适用。所以,在回答中可以引用相关的引用内容,如引用[3]关于set_difference的参数顺序影响差集方向的说明。 最后,生成相关问题,可能涉及如何处理不同方向的差集,如何优化性能,或者处理vector大小不一致的情况等。</think>以下是实现两个$std::vector<std::set<int>>$容器对应位置集合的交集与差集的方法: ### 一、实现步骤 1. **参数校验**:确保两个$std::vector$长度相同,否则无法进行对应位置操作[^3] 2. **结果容器初始化**:创建两个新的$std::vector<std::set<int>>$容器存储结果 3. **遍历计算**:对每个位置的$std::set$元素执行以下操作: - **交集**:使用$std::set\_intersection$算法 - **差集**:使用$std::set\_difference$算法(参数顺序决定差集方向) ### 二、代码实现 ```cpp #include <vector> #include <set> #include <algorithm> #include <iterator> void compute_set_operations( const std::vector<std::set<int>>& vec1, const std::vector<std::set<int>>& vec2, std::vector<std::set<int>>& intersections, std::vector<std::set<int>>& differences_A_B) { assert(vec1.size() == vec2.size()); for (size_t i = 0; i < vec1.size(); ++i) { // 计算交集 std::set<int> intersect; std::set_intersection( vec1[i].begin(), vec1[i].end(), vec2[i].begin(), vec2[i].end(), std::inserter(intersect, intersect.begin())); // 计算差集(A-B) std::set<int> diff; std::set_difference( vec1[i].begin(), vec1[i].end(), vec2[i].begin(), vec2[i].end(), std::inserter(diff, diff.begin())); intersections.push_back(intersect); differences_A_B.push_back(diff); } } ``` ### 三、特性说明 1. **时间复杂度**:每个集合操作的时间复杂度为$O(n)$,其中$n$为集合元素数量[^1] 2. **容器特性**:$std::set$的自动排序特性确保了算法的高效执行 3. **扩展性**:修改参数顺序可计算不同方向的差集(如B-A)[^3] ### 四、使用示例 ```cpp std::vector<std::set<int>> vec1 = {{1,2,3}, {4,5,6}}; std::vector<std::set<int>> vec2 = {{2,3,4}, {4,5,7}}; std::vector<std::set<int>> intersections; std::vector<std::set<int>> diffs; compute_set_operations(vec1, vec2, intersections, diffs); /* 结果: intersections = {{2,3}, {4,5}} diffs = {{1}, {6}} */ ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lucy_stone

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值