STL - 重载 STL 比较函数 & map 自带去重
问题:
重载了 string 的比较函数后,在 map 中排完序后发现去重了。
原因:
-
标准库中如何检验等价关系?
在每个标准库使用比较 (Compare) 概念的位置,以等价关系检验唯一性。不精确而言,若二个对象 a 与 b 互相比较不小于对方 : !comp(a, b) && !comp(b, a) ,则认为它们等价(非唯一)。
也就是说: 在 STL 中,我们只要重载<
就也同时确认了等价关系。 -
map 参数:std::map - cppreference
map 是自带去重的,若不需要去重,可以使用 multimap;
map 去重是根据 key 来判断的,两个键值对的 key 相同,则会被认为这两个键值对相同,因为 key 是唯一的; -
重载 STL 的比较函数
首先,std::less - cppreference 比较函数是一个结构体,我们要在结构体中重载它,且它是一个常函数。
若我们以 string 的长度作为 key,那么拥有相同长度的字符串 key 就会被判断为是同一个键值对,下面代码插入了四个相同长度的 key 的键值对,最后只输出了第一个键值对。因为三个键值对插入时被判定为已经存在,故插入的指令被忽略了。
#include<iostream>
#include<map>
#include<string>
using namespace std;
struct cmp
{
bool operator()(const string &a, const string &b) const
{
return a.size() < b.size();
}
};
map<string, string, cmp> M;
int main()
{
M.insert({"abb", "abcd"});
M.insert({"abc", "abcdefg"});
M.insert({"aac", "abcdefggg"});
M.insert({"aaa", "abcdefggdsaghsdfh"});
for(auto t : M) cout << t.first << ' ' << t.second <<endl;
return 0;
}