序列式容器和关联式容器是C++标准模板库(STL)中的两大类容器
序列式容器存储的元素在逻辑上呈现为线性序列。这些容器的共同特点是,它们允许通过位置(索引)来访问元素,且元素之间的相对位置是固定的,除非进行插入或删除操作。常见的序列式容器包括:
关联式容器存储的元素是按关键字(key)组织起来的,这些关键字用于快速查找、插入和删除元素。关联式容器通常基于平衡二叉树(如红黑树)或哈希表实现。常见的关联式容器包括:
map
set
template < class T, // key类型T
class Compare = less<T>, // Compare的比较仿函数
class Alloc = allocator<T> // 内存池
> class set;
//empty (1) 无参构造
explicit set (const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
//range (2) 迭代器区间构造
template <class InputIterator>
set (InputIterator first, InputIterator last,
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
//copy (3) 拷贝构造
set (const set& x);
//这里还有一个移动构造 移动构造函数我会但开一篇
//初始化器列表 (5)
set (initializer_list<value_type> il,
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
//迭代器 双向迭代器
iterator a bidirectional iterator to const value_type
//const迭代器
const_iterator a bidirectional iterator to const value_type
//反向迭代器
reverse_iterator reverse_iterator<iterator>
//const的反向迭代器
const_reverse_iterator reverse_iterator<const_iterator>
//正向迭代器
iterator begin()/end()
//反向迭代器
reverse_iterator rbegin()/rend()
int main() {
set<int> A;
array<int, 10>B = {0,1,2,3,4,5,6,7,8,9};
set<int> C(B.begin(), B.end());
set<int> D = {1,2,3,4,5};
return 0;
}
//成员类型
key_type The first template parameter (T)
value_type The first template parameter (T)
// 单个数据插⼊,如果已经存在则插⼊失败
pair<iterator,bool> insert (const value_type& val);
// 列表插⼊,已经在容器中存在的值不会插⼊
void insert (initializer_list<value_type> il);
// 迭代器区间插⼊,已经在容器中存在的值不会插⼊
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
// 查找val,返回val所在的迭代器,没有找到返回end()
iterator find (const value_type& val);
// 查找val,返回Val的个数
size_type count (const value_type& val) const;
// 删除⼀个迭代器位置的值
iterator erase (const_iterator position);
// 删除val,val不存在返回0,存在返回1
size_type erase (const value_type& val);
// 删除⼀段迭代器区间的值
iterator erase (const_iterator first, const_iterator last);
// 返回⼤于等val位置的迭代器
iterator lower_bound (const value_type& val) const;
// 返回⼤于val位置的迭代器
iterator upper_bound (const value_type& val) const;
set<int> A = {1,3,5,7,9};//列表构造
cout << A.insert(1).second << endl;
A.insert({2,4});
array<int, 2> arr = { 6,8 };
A.insert(arr.begin(), arr.end());
auto it = A.begin();
while (it != A.end())
cout << *it++ << " ";
cout << endl;
for (auto itt : A)
cout << itt << ' ';
cout << endl;
return 0;
//find与erase使用
set<int> A = { 1,9,2,8,3,7,4,6,5 };
for (auto it : A) cout << it << ' ';
cout << endl;
A.erase(A.begin());//删除min
for (auto it : A) cout << it << ' ';
cout << endl;
int x;
cin >> x;
if (A.erase(x) == 0)
cout << "我找不到" << endl;
for (auto it : A) cout << it << ' ';
cout << endl;
cin >> x;
if (A.find(x) != A.end())
A.erase(A.find(x));//有点刻意
else
cout << "我找不到" << endl;
for (auto it : A) cout << it << ' ';
cout << endl;
cin >> x;
//在算法库中找位置 O(N)的效率
auto pos1 = find(A.begin(), A.end(), x);
//自身查找效率为O(logn)
auto pos2 = A.find(x);
//count是对特定元素进行计数
if (A.count(x))
cout << "找到啦" << endl;
else
cout << "我找不到" << endl;
return 0;
set<int> A = { 1,9,2,8,3,7,4,6,5 };
for (auto it : A) cout << it << ' ';
cout << endl;
//在erase的删除 是[low,up)的情况 有时候可能不好操作 因为up不会被删
//所以采用lower_bound 与 upper_bound
auto low = A.lower_bound(2);
auto up = A.upper_bound(7);
A.erase(low, up);
for (auto it : A) cout << it << ' ';
cout << endl;
multiset<int> A;
A.insert(1);
A.insert(1);
A.insert(1);
A.insert(1);
A.insert(2);
for (auto it : A)
cout << it<<' ';
cout << endl;
cout<< A.count(1);
A.erase(1);
cout << endl;
cout << A.count(1);
emplate < class Key, // 关键字Key类型
class T, // 键值对Value类型
class Compare = less<Key>, // Compare仿函数
class Alloc = allocator<pair<const Key,T> > //。。。
> class map;
pair是存储键值对的玩意
typedef pair<const Key, T> value_type;
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)
{}
template<class U, class V>
pair(const pair<U, V>& pr) : first(pr.first), second(pr.second)
{}
};
template <class T1, class T2>
inline pair<T1, T2> make_pair(T1 x, T2 y)
{
return (pair<T1, T2>(x, y));
}
//empty (1) 无参构造
explicit map (const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
explicit map (const allocator_type& alloc);
//range (2) 迭代器构造
template <class InputIterator>
map (InputIterator first, InputIterator last,
const key_compare& comp = key_compare(),
const allocator_type& = allocator_type());
//copy (3)拷贝构造
map (const map& x);
map (const map& x, const allocator_type& alloc);
//move (4)移动构造 这里不提及
map (map&& x);
map (map&& x, const allocator_type& alloc);
//initializer list (5)列表构造
map (initializer_list<value_type> il,
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type())
// 迭代器是⼀个双向迭代器
iterator -> a bidirectional iterator to const value_type
// 正向迭代器
iterator begin();
iterator end();
// 反向迭代器
reverse_iterator rbegin();
reverse_iterator rend();
int main()
{
map<int, int> A;
A.insert({ 1,1 });
A.insert({ 2,2 });
A[3] = 3;
map<int, int> B(A.begin(), A.end());
map<int, int> C(B);
map<char, int> D({ { 'a','a' }, { 'b','b' }, { 'c','c' }, { 'd','d' }});
for (auto it : D)
{
cout <<it.first<< it.second <<' ';
}
auto rit = D.rbegin();
cout << endl;
while (rit != D.rend())
{
cout<<rit->first<< rit->second<<' ';
rit++;
}
return 0;
}
key_type -> The first template parameter (Key)
mapped_type -> The second template parameter (T)
value_type -> pair<const key_type,mapped_type>
// 单个数据插⼊,如果已经key存在则插⼊失败,key存在相等value不相等也会插⼊失败
pair<iterator,bool> insert (const value_type& val);
// 列表插⼊,已经在容器中存在的值不会插⼊
void insert (initializer_list<value_type> il);
// 迭代器区间插⼊,已经在容器中存在的值不会插⼊
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
// 查找k,返回k所在的迭代器,没有找到返回end()
iterator find (const key_type& k);
// 查找k,返回k的个数
size_type count (const key_type& k) const;
// 删除⼀个迭代器位置的值
iterator erase (const_iterator position);
// 删除k,k存在返回0,存在返回1
size_type erase (const key_type& k);
// 删除⼀段迭代器区间的值
iterator erase (const_iterator first, const_iterator last);
// 返回⼤于等k位置的迭代器
iterator lower_bound (const key_type& k);
// 返回⼤于k位置的迭代器
const_iterator lower_bound (const key_type& k) const;
map<int, char> n{ {1,'1'},{2,'2'} ,{3,'3'} ,{4,'4'} ,{5,'5'}, {6,'6'} };
//这里做使用
if (n.insert({ 1,'2' }).second == false)
cout << n.insert({ 1,'2' }).first->second << endl;
n.insert({ {7,'7'},{8,'8'} });
map<int, char> nn;
nn.insert(n.begin(), n.end());
if (n.find(1) != n.end())
cout << n.find(1)->second;
cout << endl;
cout << n.count(1);
n.erase(n.find(1));
n.erase(2);
n.erase(n.lower_bound(1), n.upper_bound(6));
cout << endl;
for (auto it : nn)
cout << it.second << ' ';
cout << endl;
for (auto rit : n)
cout << rit.second << ' ';
cout << endl;
iterator find (const key_type& k);
pair<iterator,bool> insert (const value_type& val);
mapped_type& operator[] (const key_type& k);
mapped_type& operator[] (const key_type& k)
{
pair<iterator, bool> ret = insert({ k, mapped_type() });
iterator it = ret.first;
return it->second;
}
/*
我来简单的解释一下过程
1.调用[]的时候 先进行插入{k,value}的行为
无论插入成功与否,都会返回一个pari的元素
pari的first 存储的是key的位置的迭代器
pari地scound存储地是bool类型 插入成功是true 失败是false
插入成功就是这里本没有数据 失败就是这里本来有数据
2.返回地pair类型存储在ret内
创建一个it迭代器指向 first
it指向key的迭代器
3.返回key指向的value
*/
map<string, string> dict;
dict.insert(make_pair("sort", "排序"));
// key不存在->插⼊ {"insert", string()}
dict["insert"];
// 插⼊+修改
dict["left"] = "左边";
// 修改
dict["left"] = "左边、剩余";
// key存在->查找
cout << dict["left"] << endl;
at()
方法或[]
操作符来查找或修改数据。如果使用[]
操作符访问一个不存在的键,map会自动插入一个具有该键和默认值的键值对。at()
成员方法,也没有重载[]
运算符。相反,multimap提供了其他查找方法,如find()
、lower_bound()
、upper_bound()
和equal_range()
,这些方法可以返回指向具有特定键的键值对的迭代器范围。insert()
方法返回一个pair<iterator, bool>
,其中迭代器指向插入的位置(或已存在的元素),而布尔值表示插入是否成功。insert()
方法只返回一个迭代器,指向插入的位置。