1、关联式容器
我们一开始接触的STL容器例如:vector,list,queue等这些容器统称为序列式容器,因为这些容器的底层为线性的数据结构,里面存储的是元素本身。
关联式容器也是用来存储数据的,不同的是里面存储的是<key, value>结构的键值对,在进行数据检索的效率更高
2.键值对
用来表示一一对应关系的数据结构,该数据结构通常有两个成员变量key和value,其中key表示键值,value表示key对应的信息。例如中英词典,将英文作为key,中文翻译作为value,这样通过一一对应的关系,我们可以使用英文找到对应的中文翻译。
3.set
set支持直接插入,也可以使用花括号或者迭代器初始化。
//插入
//set<int> s;
//s.insert(1);
//s.insert(4);
//s.insert(2);
//set<int> s = { 1, 4, 2 };花括号初始化
//迭代器初始化
vector<int> v = { 1, 4, 2 };
set<int> s(v.begin(), v.end());
set可以使用迭代器进行数据遍历,支持迭代器也就可以使用范围for,范围for的底层原理就是使用迭代器遍历。
set<int>::iterator it = s.begin();
while (it != s.end())
{
cout << *it << " ";
++it;
}
cout << endl;
for (auto e : s)
{
cout << e << " ";
}
当我们向set中插入相同元素时,set会将进行去重,并排序,即不插入相同的元素,这里的排序,是指进行的中序遍历。
我们使用erase进行元素删除时需要注意一点:下面的的find函数没有找到对应的元素时会返回迭代器的end位置,这样直接传入迭代器进行删除会报错。
set<int>::iterator pos = s.find(3);
s.erase(pos);
需要加上如下代码示例
set<int>::iterator pos = s.find(3);
if (pos != s.end())
s.erase(pos);
4.multiset
multiset和set的使用基本上没有什么差别,就是multiset可以插入重复的值。
下面这段代码输出结果为(表明find返回的值为中序遍历中第一个迭代器)
1 2 2 3 3 3
3 3 3
multiset<int> ms = {3, 1 ,2 ,3, 2, 3};
for (auto e : ms)
{
cout << e << " ";
}
cout << endl;
auto mspos = ms.find(3);
while (mspos != ms.end())
{
cout << *mspos << " ";
mspos++;
}
使用删除时,删除所有元素,除非你给的参数为迭代器。
5.map
map内存储的是pair结构体。下图为pair的结构
下面介绍3种插入方式
map<string, string> dict;
//创建pair对象进行插入
//pair<string, string> kv("right", "右");
//dict.insert(kv);
//创建pair匿名对象进行插入
//dict.insert(pair<string, string>("right", "右"));
//typedef pair<string, string> kv;
//dict.insert(kv("right", "右"));
dict.insert(make_pair("right", "右"));//通常这样插入比较方便
使用迭代器遍历(这里迭代器返回的是pair结构体指针)所以我们也可以使用it->first的方式进行访问。
dict.insert(make_pair("right", "右"));//通常这样插入比较方便
dict.insert(make_pair("left", "左"));
dict.insert(make_pair("good", "好"));
auto it = dict.begin();
while (it == dict.end())
{
cout << (*it).first << ' ' << it->second;
it++;
}
cout << endl;
return 0;
值得一提的是map是支持使用[]进行访问的(使用[]时如果找到了该元素则返回pair中的second引用,如果没有该元素,则将该元素插入后再返回对应的pair的second的引用)所以下面的代码对arr数组中的元素进行了统计次数的操作。
map<string, int> countMap;
string arr[] = {"1a", "2b", "2b", "3c", "3c", "3c"};
for (auto& str : arr)
{
countMap[str]++;
}
for (auto it : countMap)
{
cout << it.first << ": " << it.second << endl;
}
下面为对[]操作符的重载(insert会返回一个pair<iterator, bool>类型的结构体,map中没有该元素插入返回插入成功的的迭代器,布尔值为true,map中已经有该元素,返回已存在的迭代器,布尔值为false)所以不管插入成功与否都会返回该元素的迭代器。