c++比较器——priority_queue用 ; unordered_map 自定义哈希函数
文章目录
- priority_queue
- 自定义比较方法
- 对 比较对象结构体 重载 <
- 仿函数
- 为什么是传一个类
- std::less<T> 和 std::greater<T>
- lambda
- unordered_map
- 自定义哈希函数
- 仿函数
- lambda
priority_queue
template<
class T,
class Container = std::vector<T>,
class Compare = std::less<typename Container::value_type>
> class priority_queue;
自定义比较方法
往往算法可能需要自定义比较逻辑(如 dijkstra需要比较对应路径的长度)
重写方法:
注意都是子节点跟父节点比(堆一般是二叉树)
对 比较对象结构体 重载 <
struct Node {
int id;
int weight;
bool operator<(const Node& other) const {
return weight > other.weight; // 注意:反过来才能构成最小堆
}
};
std::priority_queue<Node> pq; // 使用默认 std::less<Node>
仿函数
就是对类重载 () 运算符。 注意是传递类!
struct cmp {
bool operator()(const Node& a, const Node& b) {
return a.weight > b.weight; // 最小堆
}
};
std::priority_queue<Node, std::vector<Node>, cmp> pq;
为什么是传一个类
template<
class T,
class Container = std::vector<T>,
class Compare = std::less<typename Container::value_type>
> class priority_queue;
这里的 Compare 是一个类型(class),而模板本来也是类型
STL是这样使用他的
Compare comp; // 默认构造一个比较器对象
if (comp(a, b)) { ... } // 用这个对象来比较
std::less 和 std::greater
<functional>
template <class T>
struct less {
bool operator()(const T& a, const T& b) const {
return a < b;
}
};
template <class T>
struct greater {
bool operator()(const T& a, const T& b) const {
return a > b;
}
};
lambda
auto cmp = [](const Node& a, const Node& b) {
return a.weight > b.weight;
};
std::priority_queue<Node, std::vector<Node>, decltype(cmp)> pq(cmp);
lambda 表达式对象,是一个匿名类的实例:
上述 cmp 是一个对象实例! 毕竟调用其方法需要一个实例,而一个实例也可以无限用。
class __lambda_123 {
public:
bool operator()(const Node& a, const Node& b) const {
return a.weight > b.weight;
}
} cmp;
unordered_map
template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<const Key, T>>
> class unordered_map;
自定义哈希函数
像 std::pair<int, int> 这样的类型标准库没有默认的 std::hash 特
化,因此需要自己提供一个哈希函数。
std::hash<T>
是标准库提供的模板类特化,专门用于哈希表。
(对于 int 这样的类型,一般就返回它本身。unordered_map 的内部机制可能会取模)
std::hash<int> h;
std::size_t hash_value = h(42); // 计算 42 的哈希值
仿函数
#include <unordered_map>
#include <utility>
struct pair_hash {
std::size_t operator()(const std::pair<int, int>& p) const {
return std::hash<int>()(p.first) ^ (std::hash<int>()(p.second) << 1);
}
};
std::unordered_map<std::pair<int, int>, std::string, pair_hash> my_map;
( pair 默认支持 == )
lambda
(C++14/17 起支持 构造函数中显式传入 hash/equal 对象)
哈希方法和比较方法:
auto hash_fn = [](const std::pair<int, int>& p) {
return std::hash<int>()(p.first) ^ (std::hash<int>()(p.second) << 1);
};
auto equal_fn = [](const std::pair<int, int>& a, const std::pair<int, int>& b) {
return a == b;
};
std::unordered_map<std::pair<int, int>, std::string, decltype(hash_fn), decltype(equal_fn)> my_map(0, hash_fn, equal_fn);