关联式容器和序列式容器是 C++ 中两种不同的容器类型
std::set
, std::map
, std::multiset
, std::multimap
等。<key, value>
结构)的概念,通过键==(key)来唯一标识元素==。std::vector
, std::list
, std::deque
, std::array
等。pair
在C++中,键值对是一种数据结构,通常用于表示关联关系 键值对由两部分组成:键(Key)和值(Value)。这种结构允许通过键来检索和关联对应的值,key代表键值,value表示与key对应的信息
std::pair
是C++标准库中提供的一个简单的键值对实现。它包含在 <utility>
头文件中。一个 std::pair
有两个公有成员:first
和 second
,分别表示键和值==(first<= =>key ; second<= =>value)==
STL中关于键值对的定义:
template <class T1, class T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair() //构造函数
: first(T1()), second(T2())
{}
pair(const T1& a, const T2& b) //拷贝构造
: first(a), second(b)
{}
};
文档中的构造函数的介绍:
pair();
std::pair
对象,不包含任何值。template<class U, class V> pair (const pair<U,V>& pr);
std::pair
对象 pr
中复制键值对来构造一个新的 std::pair
对象。pair (const first_type& a, const second_type& b);
a
和 b
,分别用于初始化 std::pair
对象的 first
和 second
成员变量。void test_pair()
{
pair<int, char> p1;//空参
pair<int, char> p2(2, '2');
pair<int, char> p3(p2);//拷贝构造
cout << p1.first << " " << p1.second << endl;;
cout << p2.first << " " << p2.second << endl;
cout << p3.first << " " << p3.second << endl;
}
int main()
{
test_pair();
return 0;
}
{}
-简化创建过程void test_pair2()
{
auto p4 = make_pair(2, 'c');//使用make_pair
pair<int, char> p5 = { 3,'d' };//c++11后,使用{ }
cout << p4.first << " " << p4.second << endl;
cout << p5.first << " " << p5.second << endl;
}
int main()
{
test_pair2();
return 0;
}
我们能使用
{}
(初始化列表),是因为:构造函数匹配。如果使用花括号进行初始化,编译器会尝试匹配合适的构造函数。对于pair
,存在接受两个参数的构造函数,因此可以通过初始化列表直接构造键值对
void test_set1()
{
set<int> s1;
vector<int> v = { 1,2,3,4,5 };
set<int> s2(v.begin(), v.end());//利用迭代区间
set<int> s3 = s2;//拷贝构造
for (auto e : s1)
{
cout << e << " ";
}
cout << endl;
for (auto e : s2)
{
cout << e << " ";
}
cout << endl;
for (auto e : s3)
{
cout << e << " ";
}
cout << endl;
}
int main()
{
test_set1();
return 0;
}
函数声明 | 功能 |
---|---|
iterator begin(); | 返回指向set开头的迭代器 |
iterator end(); | 返回指向set最后一个元素后面的迭代器 |
const_iterator cbegin() const; | 返回指向set开头的const迭代器 |
const_iterator cend() const; | 返回指向set最后一个元素后面的const迭代器 |
reverse_iterator rbegin(); | 返回指向set最后一个元素的反向迭代器 |
reverse_iterator rend(); | 返回指向set第一个元素前面的反向迭代器 |
const_reverse_iterator crbegin() const; | 返回指向set最后一个元素的反向const迭代器 |
const_reverse_iterator crend() const; | 返回指向set第一个元素前面的反向const迭代器 |
声明:pair<iterator, bool> insert(const value_type& val);
true
。false
。pair
对象,包含插入的迭代器和插入是否成功的标志。函数声明 | 功能介绍 | 返回值 |
---|---|---|
iterator erase(iterator position); | 删除指定位置的元素,并返回指向被删除元素之后元素的迭代器。 | 指向被删除元素之后元素的迭代器。 |
size_type erase(const key_type& k); | 删除 set 中所有等于指定键值的元素。返回删除的元素个数。 | 删除的元素个数。 |
iterator erase(iterator first, iterator last); | 删除区间 [first, last) 中的所有元素,并返回最后一个被删除元素之后的迭代器。 | 指向被删除元素之后元素的迭代器。 |
find
函数用于在 set
中查找指定键值的元素,并返回指向该元素的迭代器。如果元素不存在,则返回 end()
。
声明:size_type count (const key_type& k) const;
count
函数用于统计 set
中与指定键值相等的元素个数。由于 set
中元素的键值是唯一的,因此该函数的返回值要么是 0(元素不存在),要么是 1(元素存在)。
void test_set2()
{
// 排序+去重
set<int> s;
s.insert(5);
s.insert(1);
s.insert(6);
s.insert(3);
s.insert(5);
s.insert(1);
for (auto e : s)
{
cout << e << " ";
}
cout << endl;
set<int>::iterator pos = s.find(5);//找到5就删除
if (pos != s.end())
{
cout << "找到了" << endl;
s.erase(pos);
}
for (auto e : s)
{
cout << e << " ";
}
cout << endl;
if (s.count(1))
{
cout << "1在" << endl;
}
else
{
cout << "1不在" << endl;
}
}
int main()
{
test_set2();
return 0;
}
注意:
multiset
是 C++ 标准库中的关联式容器之一,属于有序容器。与 set
不同的是,multiset
允许键值重复,即可以包含相同键值的多个元素。
multiset
允许容器中存在相同的键值,因此可以包含多个相同键值的元素。
set
类似,multiset
也维护元素的有序性,根据键值进行排序。
multiset
。[]
中放入key,就可以找到与key对应的value。
key: 键值对中key的类型 T: 键值对中value的类型 Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递) Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器
void testmap1()
{
map<string, string> m1;//空的
map<string, string> m2(m1);//拷贝构造
}
[]
重载下面是关于 multiset
中成员函数 begin()
, end()
, cbegin()
, cend()
, rbegin()
, rend()
, crbegin()
, 和 crend()
的函数声明和功能介绍:
函数声明 | 功能介绍 |
---|---|
iterator begin(); | 返回 multiset 中首元素的位置的迭代器。 |
iterator end(); | 返回 multiset 中最后一个元素后面的位置的迭代器。 |
const_iterator cbegin() const; | 返回 multiset 中首元素的位置的 const 迭代器,不能修改所指向的元素。 |
const_iterator cend() const; | 返回 multiset 中最后一个元素后面的位置的 const 迭代器,不能修改所指向的元素。 |
reverse_iterator rbegin(); | 返回指向 multiset 中第一个元素的反向迭代器,即 end()。 |
reverse_iterator rend(); | 返回指向 multiset 中最后一个元素下一个位置的反向迭代器,即 rbegin()。 |
const_reverse_iterator crbegin() const; | 返回指向 multiset 中第一个元素的反向 const 迭代器,不能修改所指向的元素。 |
const_reverse_iterator crend() const; | 返回指向 multiset 中最后一个元素下一个位置的反向 const 迭代器,不能修改所指向的元素。 |
void testmap2()
{
map<string, string> m1;//空的
m1.insert(pair<string, string>("sort", "排序"));//匿名对象
m1.insert(make_pair("apple", "苹果"));//使用make_pair函数
m1.insert({ "apple", "苹果" });// C++11 多参数隐式类型转换(构造函数支持)
}
在
map
中,find
函数用于查找指定键的元素,并返回指向该元素的迭代器。如果找到了指定的键,则返回指向该键值对的迭代器;如果未找到,则返回指向map
末尾的迭代器。
函数声明 | 功能介绍 |
---|---|
iterator find(const key_type& k); | 查找键值为 k 的元素,并返回一个指向该元素的迭代器。如果 k 存在于 map 中,则返回指向该元素的迭代器;如果不存在,则返回指向 map 末尾的迭代器。 |
const_iterator find(const key_type& k) const; | 在常量 map 中查找键值为 k 的元素,并返回一个指向该元素的迭代器。如果 k 存在于 map 中,则返回指向该元素的迭代器;如果不存在,则返回指向 map 末尾的迭代器。 |
[]
[]
运算符时
map
中,则返回与该键关联的值[]
运算符向 map
中插入元素时
void testmap3()
{
map<string, string> m1;//空的
m1.insert(pair<string, string>("sort", "排序"));//匿名对象
m1.insert(make_pair("apple", "苹果"));//使用make_pair函数
m1.insert({ "left", "左边" });// C++11 多参数隐式类型转换(构造函数支持)
for (auto& kv : m1)
{
cout << kv.first << ":" << kv.second << " ";
}
cout << endl;
m1["right"];//这是插入一个right(key)
m1["apple"] = "青苹果";//这里是进行修改
for (auto& kv : m1)
{
cout << kv.first << ":" << kv.second << " ";
}
cout << endl;
}
int main()
{
testmap3();
return 0;
}
注意