目录
一、vector
1.vector的定义和特性
C++中,vector是一个动态数组容器,可以存储一系列相同类型的元素,它是标准库<vector>中定义的模板类。
vector的定义和结构非常简单,它由以下几个重要的部分组成:模板类声明:vector是一个模板类,因此在使用之前需要包含头文件<vector>。声明一个vector对象的通用语法如下:
std::vector<T> vec;
//这里的T是要存储在vector中的元素类型。
容器大小:vector是一个动态数组,可以根据需要自动调整大小。它会根据元素的数量动态分配内存空间。
元素访问:可以通过索引来访问vector中的元素。索引从0开始,最后一个元素的索引是size()1。可以使用[]运算符或at()函数来访问元素。
元素添加和删除:可以使用pushback()函数在vector的末尾添加元素,使用popback()函数删除末尾的元素。还可以使用insert()函数在指定位置插入元素,使用eraseO函数删除指定位置的元素。
容器大小管理:可以使用size()函数获取vector中元素的数量,使用empty()函数检查vector是否为空。还可以使用resize()函数调整vector的大小。
迭代器:vector提供了迭代器,可以用于遍历容器中的元素。可以使用begin0函数获一个元素的迭代器,使用end()函数获取指向最后一个元素之后位置的迭代器。
2.vector的常用函数
push back():将元素添加到vector的末尾。
void push_ back(const T& value);
pop_back():删除vector末尾的元素
void pop_back();
begin()和end():返回指向vector第一个元素和最后一个元素之后位置的迭代器。
示例:
vector<int> vec = {10, 20, 30};
for (auto it = vec begin(); it != vec.end(); ++it)
{
cout << "it << " ";
}
3.vector排序去重
排序:
要对vector进行排序,可以使用标准库中的sort函数。该函数位于头文件<algorithm>中。
示例:
#include <algorithm>
std::vector<T> vec ={...};
std::sort(vec.begin(),vec.end());
这里的T是vector中元素的类型。
sort函数接受两个迭代器参数,表示要排序的范围。
vec.begin()返回指向vector第一个元素的迭代器
vec.end()返回指向最后一个元素之后位置的迭代器。
去重:要去除vector中的重复元素,可以使用std::unique函数。该函数位于头文件<algorithm>中
示例:
#include <algorithm>
std::vector<T> vec ={...};
std::sort(vec.begin(),vec.end());
auto last = std::unique(vec.begin(), vec.ebd());
vec.erase(last, vec.end());
首先,需要对vector进行排序,以便相同的元素相邻。然后,std::unique函数将重复的元素移动到vector的末尾,并返回一个指向不重复元素的迭代器。最后,可以使用vec.erase函数将重复元素从vector中删除
示例:
#include<iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> vec = {2,1,3,2,4,1,5,4);
std::sort(vec,begin(),vec.end());
auto last = std::unique(vec.begin(),vec.end());
vec.erase(last, vec.end());
for(const auto& num:vec)
{
std::cout << num<<” ";
}
return 0;
}
输出:
12345
这样,vector中的重复元素被去除,只保留了不重复的元素,
二、map
1.map
map是一种关联容器,用于存储一组键值对(key-value pairs),其中每个键(key)都是唯一的。
map容器根据键来自动进行排序,并且可以通过键快速查找对应的值。map容器使用红黑树(Red-Black Tree)数据结构来实现,具有较快的插入、删除和査找操作的时间复杂度0(logn)。
map的定义和结构如下:
template < class Key, class T,class Compare = less<Key>,
class Allocator = allocator<pair<const Key, T>>>
class map ;
Key: 表示存储在map中的键(key)的类型
T: 表示存储在map中的值(value)的类型:
Compare: 表示用于比较键的函数对象的类型,默认为less,使用键类型的默认比较函数
Allocator: 表示用于分配内存的分配器类型,默认为allocator。
函数 lower_bound upper_bound | 功能 返回指向第一个不小于指定键的元素位置 | 时间复杂度 o(log n) o(log n) o(log n) o(log n) o(1) o(1) o(1) o(n) O(1) o(log n) o(log n) |
2.multimap
multimap是一种关联容器,类似于map,但允许存储多个具有相同键的键值对。
在实际做题过程中,multimap几乎用不到。
3.unordered_map
unordered_map是一种关联容器,用于存储一组键值对(key-value pairs),其中每个键(key)都是唯一的。与map和mwultimap不同,umordered_map不会根据键的顺序进行排序,而是使用哈希函数将键映射到存储桶中。这使得unordered_map具有更快的插入、删除和査找操作的时间复杂度,但不保证元素的顺序。
unordered map的定义和结构如下:
emplate <class Key,class T, class Hash = hash<Key>,
class KeyEqual = equal_to<Key>,
class Allocator = allocator<pair<const Key, T>>>
class unordered map;
·Key:表示存储在unorderedmap中的键(key)的类型
·T:表示存储在unorderedmap中的值(value)的类型
·Hash:表示用于计算键的哈希值的函数对象的类型,默认为hash,使用键类型的默认哈希函数。
·KeyEqual:表示用于比较键的函数对象的类型,默认为equal_to,使用键类型的默认比较函数。
·Allocator:表示用于分配内存的分配器类型,默认为allocator。
函数 insert erase find count size empty clear | 功能 插入元素 删除元素 查找元素 计数指定键的元素个数 返回元素个数 判断容器是否为空 清空容器 | 平均时间复杂度 0(1) o(1) 0(1) 0(1) 0(1) 0(1) 0(1) | 最坏时间复杂度簣浗頑还 0(n) 0(m) 0(m) 0(m) 0(1) 0(1) o(n) |
unordered map拥有极好的平均时间复杂度和极差的最坏时间复杂度,所以他的时间复杂度是不稳定的。
一般情况下我们更愿意使用复杂度稳定的map而不是unordered map.
三、stack
1.stack的定义和结构
stack是一种后进先出(LIF0)的数据结构,使用前需要包含头文件<stack>。stack提供了一组函数来操作和访问元素,但它的功能相对较简单。stack的定义和结构如下:
template<class T, class Container = deque<T>>
class stack;
template<class T,class (ontainer = deque<T>>
class stack;
T: 表示存储在stack中的元素的类型。
Container: 表示底层容器的类型,默认为deque。也可以使用其他容器类型,如vector或list。
stack的内部实现使用了底层容器来存储元素,并且只能通过特定的函数来访问和操作元素。
函数 empty() size() | 描述 检查栈是否为空 | 时间复杂度 0(1) |
四、pair
1.pair的定义和结构
在C++中,pair是一个模板类,用于表示一对值的组合。它位于<utility>头文件中。
pair类的定义如下:
template<class T1, class T2>
struct pair
{
T1 first; // 第一个值
T2 second; // 第二个值
//构造函数
pair();
pair(const T1& x, const T2& y);
//比较运算符重载
bool operator == (const pair& rhs)const;
bool operator != (const pair& rhs)const;
}
pair类模板有两个模板参数,T1和T2,分别表示第一个值和第二个值的类型。
pair类有两个成员变量,first和second,分别表示第一个值和第二个值。
pair类还有一些成员函数和特性,例如默认构造函数、带参数的构造函数、比较运算符重载等。
使用pair类,你可以方便地将两个值组合在一起,并进行传递、存储和操作。
例如,可以将两个整数组合在一起作为回值,或者将一对值存储在容器中。
下面是一些使用pair的示例:
#include<iostream>
#include <utility>
int main()
{
std::pair<int, double> p1(1, 3.14);
std: :pair<char, std::string> p2('a', "hello");
std: :cout << p1.first <<“,"<<p1.second << std::endl;
std::cout << p2.first<<","<<p2.second << std: :endl;
return 0;
}
以上代码创建了两个pair对象,分别包含不同类型的值。然后,通过访问first和second成员变量,输出了这些值
2.pair的嵌套
pair可以进行嵌套,也就是说可以将一个pair对象作为另一个pair对象的成员。通过嵌套pair,你可以方便地组合多个值,并形成更复杂的数据结构。
例如,你可以创建一个三维坐标系的点,其中第1个维度由一个整数表示,第2、3个维度由一个pair表示。
下面是一个示例代码,演示了如何嵌套使用pair:
#include <utility>
#include<iostream>
int main()
{
std::pair <int, int> p1(1, 2);
std::pair <int, std::pair <int, int> > p2(3, std:: make_pair(4, 5));
std::pair <std::pair <int, int>, std::pair <int, int> >> p3( std:: make_pair(6, 7), std:: make_pair);
std::cout << p1.first << ", " << p1.second << std:: endl;
std::cout << p2.first << ", " << p2.second.first << ", " << p2.second.second << std:: endl;
std::cout << p3.first .first<< ", " << p3.first. second << ", " << p3.second. first << " " <<std:: endl;
return 0;
}
在这个示例中,我们创建了三个pair对象:p1、p2和p3。
·P1是一个简单的pair,包含两个整数值。
·p2是一个嵌套的pair,其中第一个值是一个整数,第二个值是一个pair,其中包含两个整数
·p3是一个嵌套的pair,其中每个值都是一个pair,每个pair包含两个整数值。通过访问嵌套的pair对象的成员变量,我们可以获取到相应的值。
3.pair自带的排序规则
pair自带的排序规则是按照first成员进行升序排序。
如果first成员相等,则按照second成员进行升序排序这意味着当你使用标准库中的排序算法(如std::sort)对包含pair对象的容器进行排序时,会根据pair对象的first成员进行排序。
下面是一个示例代码,演示了如何使用pai进行排序:
#include <iostream>
#include <utility>
#include <vector>
#include <algorithm>
int main()
{
std::vector<std::pair<int, int>> vec
vec.push back(std::make_pair(3,2));
vec.push back(std::nake pair(1, 4))
vec.push back(std::mgke pair(2,1));
std::sort(vec.begin(), vec.end());
for(const auto& p : vec)
{
std::cout << p.first<<","<< p.second << std: :endl;
}
return 0;
}
在这个示例中,我们创建了一个存储pair对象的向量vec,其中包含三个pair对象。然后,我们使用std::sort函数对vec进行排序。由于pair对象的排序规则是按照first成员进行升序排序,所以排序后的结果
1 | 4 |
2 | 1 |
3 | 2 |
最后,我们通过遍历vec并输出每个pair对象的成员,验证了排序结果。需要注意的是,如果你想按照其他排序规则对pair进行排序,可以自定义比较函数或使用lambda表达式来传递给排序算法。这样,你可以根据自己的需求定义排序规则