【C++STL基础入门】vector运算和遍历、排序、乱序算法

简介: 【C++STL基础入门】vector运算和遍历、排序、乱序算法

前言


C++标准库提供了丰富的容器和算法,其中vector是最常用的容器之一。它以动态数组的形式存储元素,并提供了许多方便的运算符和算法来操作和处理数据。本文将介绍vector的基本运算、遍历方法、排序算法以及乱序算法。通过学习这些内容,您将能够更加灵活、高效地使用vector容器。


一、vector运算符


1.1 比较运算符


vector有哪些比较运算符?

在vector中,有下面这些比较运算符的重载

1、v1 == v2

2、v1 != v2

3、v1 <= v2

4、v1 >= v2

5、v1 < v2

6、v1 > v2

示例代码

#include <iostream>
#include <vector>
int main() {
    std::vector<int> v1 = {1, 2, 3};
    std::vector<int> v2 = {1, 2, 3};
    // v1 == v2
    if (v1 == v2)
        std::cout << "v1 is equal to v2" << std::endl;
    else
        std::cout << "v1 is not equal to v2" << std::endl;
    // v1 != v2
    if (v1 != v2)
        std::cout << "v1 is not equal to v2" << std::endl;
    else
        std::cout << "v1 is equal to v2" << std::endl;
    // v1 <= v2
    if (v1 <= v2)
        std::cout << "v1 is less than or equal to v2" << std::endl;
    else
        std::cout << "v1 is greater than v2" << std::endl;
    // v1 >= v2
    if (v1 >= v2)
        std::cout << "v1 is greater than or equal to v2" << std::endl;
    else
        std::cout << "v1 is less than v2" << std::endl;
    // v1 < v2
    if (v1 < v2)
        std::cout << "v1 is less than v2" << std::endl;
    else
        std::cout << "v1 is not less than v2" << std::endl;
    // v1 > v2
    if (v1 > v2)
        std::cout << "v1 is greater than v2" << std::endl;
    else
        std::cout << "v1 is not greater than v2" << std::endl;
    return 0;
}


145395f2754144698f95700cf9b7b393.png

输出结果:

v1 is equal to v2
v1 is not equal to v2
v1 is less than or equal to v2
v1 is greater than or equal to v2
v1 is not less than v2
v1 is not greater than v2


注意

这些运算符对vector进行按元素比较,如果两个vector的元素数量相同且对应位置的元素相等,则认为它们是相等的。而在大小比较方面,会比较两个vector的字典序。


1.2 下标运算符

在前面我们已经讲过了vector的下标运算符了,在这里我们直接看一个示例代码吧

示例代码如下:

#include <iostream>
#include <vector>
int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};
    // 获取指定索引位置的元素值
    int index = 2;
    int value = v[index];
    std::cout << "Value at index " << index << ": " << value << std::endl;
    return 0;
}


fc9ef2b5363c4c12ab5dbddda18e232b.png

输出结果:

Value at index 2: 3


在这个示例代码中,我们创建了一个整数类型的vector v,然后使用方括号运算符 [] 获取了索引为2的元素值,并将其存储到整数变量 value 中。最后,我们将索引和对应的值输出到控制台。

请注意,向量的索引是从0开始的,因此索引2对应着第3个元素。在示例中,我们获取到了索引为2的元素,其值为3。


二、算法


2.1 算法需要的头文件

#include <algorithm>


2.2 遍历算法

函数原型:

template<class InputIterator, class Function>
Function for_each(InputIterator _First,  InputIterator _Last, Function _Func );


函数模板for_each用于对指定范围内的元素应用一个函数,它接受以下参数:


InputIterator _First:这是一个迭代器,指向要应用函数的范围的第一个元素。

InputIterator _Last:这是一个迭代器,指向应用函数范围后面的一个位置(即不包含在范围内)。

Function _Func:这是一个可调用对象(函数、函数指针、lambda表达式等),它将被应用于范围内的每个元素。

for_each函数会按顺序遍历范围内的每个元素,并将每个元素作为参数传递给函数_Func进行处理。


示例代码如下所示:

#include <iostream>
#include <vector>
#include <algorithm>
void display(int num) {
    std::cout << num << " ";
}
int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};
    std::cout << "Elements in vector: ";
    std::for_each(v.begin(), v.end(), display);
    std::cout << std::endl;
    return 0;
}


37660735cc1342d39afd87a65e0bb8ee.png


输出结果:

Elements in vector: 1 2 3 4 5


在这个示例代码中,我们创建了一个整数类型的vector v,并初始化它的元素。然后,我们定义了一个名为display的函数,用于输出传入的参数。接下来,我们使用for_each函数遍历整个vector,并将每个元素作为参数传递给display函数进行处理,从而显示出vector中的所有元素。


2.3 排序算法

从大到小

函数原型:

template<class RandomAccessIterator>
void sort(RandomAccessIterator _First, RandomAccessIterator _Last );


函数sort是C++标准库中的一个排序算法,它用于对指定范围内的元素进行排序。下面是sort函数的参数解释:


1.RandomAccessIterator _First:这是一个迭代器,指向要排序范围的第一个元素。

2.RandomAccessIterator _Last:这是一个迭代器,指向排序范围后面的一个位置(即不包含在排序范围内)。


sort函数通过比较迭代器指向的元素来对范围进行排序,它可以用于各种类型的容器(如vector、array等)或原始数组。排序范围的开始位置由迭代器_First表示,结束位置由迭代器_Last表示。


示例代码如下所示:

#include <iostream>
#include <vector>
#include <algorithm>
int main() {
    std::vector<int> v = {5, 2, 8, 3, 1};
    std::cout << "Before sorting: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    std::sort(v.begin(), v.end());
    std::cout << "After sorting: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}


7c72a85a9d9c44e9b97c667c0c9a3dcd.png


输出结果:

Before sorting: 5 2 8 3 1
After sorting: 1 2 3 5 8


在这个示例代码中,我们创建了一个整数类型的vector v,并初始化它的元素。然后,我们使用sort函数对整个vector进行排序,通过v.begin()表示排序范围的开始位置,通过v.end()表示排序范围的结束位置。最后,我们输出排序前后的vector元素以验证排序结果。

希望这个例子能帮助您理解sort函数和其参数的使用!


从小到大

函数原型:

template<class RandomAccessIterator, class Pr>
void sort( RandomAccessIterator _First,  RandomAccessIterator _Last, BinaryPredicate _Comp);


函数sort是C++标准库中的一个排序算法,它用于对指定范围内的元素进行排序。下面是sort函数的参数解释:


RandomAccessIterator _First:这是一个迭代器,指向要排序范围的第一个元素。

RandomAccessIterator _Last:这是一个迭代器,指向排序范围后面的一个位置(即不包含在排序范围内)。

BinaryPredicate _Comp:这是一个二元谓词(函数对象或lambda表达式),用于指定元素的比较方式。

sort函数按照指定的比较规则对范围内的元素进行排序。排序范围的开始位置由迭代器_First表示,结束位置由迭代器_Last表示。比较规则由提供的二元谓词_Comp定义,用于比较两个元素的关系。默认情况下,如果不提供_Comp参数,sort函数将使用默认的比较操作符(<)进行排序。


示例代码如下所示:

#include <iostream>
#include <vector>
#include <algorithm>
bool compare(int a, int b) {
    return a > b;
}
int main() {
    std::vector<int> v = {5, 2, 8, 3, 1};
    std::cout << "Before sorting: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    std::sort(v.begin(), v.end(), compare);
    std::cout << "After sorting: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}


c86f3a7e4ec446bb9ac4897e30d8cb68.png

输出结果:

Before sorting: 5 2 8 3 1
After sorting: 8 5 3 2 1


在这个示例代码中,我们创建了一个整数类型的vector v,并初始化它的元素。然后,我们定义了一个名为compare的二元谓词函数,用于按照降序对元素进行排序。接下来,我们使用sort函数对整个vector进行排序,通过v.begin()表示排序范围的开始位置,通过v.end()表示排序范围的结束位置,并传递自定义的比较函数compare作为第三个参数。最后,我们输出排序前后的vector元素以验证排序结果。


需要知道的事情:参数三 greater<>() 可以指定从大到小,其实他就是一个自定义的比较函数而已


2.4 乱序算法

函数原型:

void random_shuffle(RandomAccessIterator _First, RandomAccessIterator _Last );


函数random_shuffle是C++标准库中的一个算法,用于将指定范围内的元素进行随机重排。下面是random_shuffle函数的参数解释:


RandomAccessIterator _First:这是一个迭代器,指向要进行随机重排范围的第一个元素。

RandomAccessIterator _Last:这是一个迭代器,指向随机重排范围后面的一个位置(即不包含在范围内)。

random_shuffle函数通过随机交换元素的位置来实现重排。重排范围的开始位置由迭代器_First表示,结束位置由迭代器_Last表示。


示例代码如下所示:

#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};
    std::cout << "Before shuffling: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    std::random_device rd;
    std::mt19937 g(rd());
    std::shuffle(v.begin(), v.end(), g);
    std::cout << "After shuffling: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}


9c08da739108417890b8d060eb1211fa.png

输出结果:

Before shuffling: 1 2 3 4 5
After shuffling: 3 5 1 2 4


在这个示例代码中,我们创建了一个整数类型的vector v,并初始化它的元素。然后,我们使用random_device和mt19937来生成一个随机数引擎对象 g。接下来,我们使用shuffle函数将整个vector随机重排,通过v.begin()表示重排范围的开始位置,通过v.end()表示重排范围的结束位置,并传递生成的随机数引擎对象g作为第三个参数。最后,我们输出重排前后的vector元素以验证结果。


乱序算法想看详细的请到C++11专栏进行了解:C++11保姆级教程----专栏


总结


本文介绍了vector容器的基本运算符和常用算法,包括遍历、排序和乱序。通过使用这些运算符和算法,我们可以更方便地操作和处理vector中的元素,提高代码的灵活性和效率。在实际开发中,根据需求选择合适的运算符和算法,将有助于更好地利用C++STL的强大功能。


希望本文对您理解vector的运算和算法有所帮助。谢谢阅读!

相关文章
|
5月前
|
存储 算法
算法入门:专题二---滑动窗口(长度最小的子数组)类型题目攻克!
给定一个正整数数组和目标值target,找出总和大于等于target的最短连续子数组长度。利用滑动窗口(双指针)优化,维护窗口内元素和,通过单调性避免重复枚举,时间复杂度O(n)。当窗口和满足条件时收缩左边界,更新最小长度,最终返回结果。
|
5月前
|
存储 算法
算法入门:专题一:双指针(有效三角形的个数)
给定一个数组,找出能组成三角形的三元组个数。利用“两边之和大于第三边”的性质,先排序,再用双指针优化。固定最大边,左右指针从区间两端向内移动,若两短边之和大于最长边,则中间所有组合均有效,时间复杂度由暴力的O(n³)降至O(n²)。
|
5月前
|
存储 算法 编译器
算法入门:剑指offer改编题目:查找总价格为目标值的两个商品
给定递增数组和目标值target,找出两数之和等于target的两个数字。利用双指针法,left从头、right从尾向中间逼近,根据和与target的大小关系调整指针,时间复杂度O(n),空间复杂度O(1)。找不到时返回{-1,-1}。
|
8月前
|
机器学习/深度学习 数据采集 算法
你天天听“数据挖掘”,可它到底在“挖”啥?——数据挖掘算法入门扫盲篇
你天天听“数据挖掘”,可它到底在“挖”啥?——数据挖掘算法入门扫盲篇
187 0
|
算法 编译器 C++
模拟实现c++中的vector模版
模拟实现c++中的vector模版
|
12月前
|
机器学习/深度学习 算法 机器人
强化学习:时间差分(TD)(SARSA算法和Q-Learning算法)(看不懂算我输专栏)——手把手教你入门强化学习(六)
本文介绍了时间差分法(TD)中的两种经典算法:SARSA和Q-Learning。二者均为无模型强化学习方法,通过与环境交互估算动作价值函数。SARSA是On-Policy算法,采用ε-greedy策略进行动作选择和评估;而Q-Learning为Off-Policy算法,评估时选取下一状态中估值最大的动作。相比动态规划和蒙特卡洛方法,TD算法结合了自举更新与样本更新的优势,实现边行动边学习。文章通过生动的例子解释了两者的差异,并提供了伪代码帮助理解。
951 2
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
611 3
|
存储 编译器 C语言
【c++丨STL】vector模拟实现
本文深入探讨了 `vector` 的底层实现原理,并尝试模拟实现其结构及常用接口。首先介绍了 `vector` 的底层是动态顺序表,使用三个迭代器(指针)来维护数组,分别为 `start`、`finish` 和 `end_of_storage`。接着详细讲解了如何实现 `vector` 的各种构造函数、析构函数、容量接口、迭代器接口、插入和删除操作等。最后提供了完整的模拟实现代码,帮助读者更好地理解和掌握 `vector` 的实现细节。
336 0
|
存储 编译器 C语言
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
835 5
|
数据采集 存储 算法
【C++数据结构——图】图的遍历(头歌教学实验平台习题) 【合集】
本文介绍了图的遍历算法,包括深度优先遍历(DFS)和广度优先遍历(BFS)。深度优先遍历通过递归方式从起始节点深入探索图,适用于寻找路径、拓扑排序等场景;广度优先遍历则按层次逐层访问节点,适合无权图最短路径和网络爬虫等应用。文中提供了C++代码示例,演示了如何实现这两种遍历方法,并附有测试用例及结果,帮助读者理解和实践图的遍历算法。
765 0