一. std::unordered_map 与 hash
在C++中,std::unordered_map 是一个基于哈希表的关联容器,它允许你以常数平均时间复杂度存储和检索键值对。默认情况下,std::unordered_map 使用 std::hash 模板类来生成键的哈希值。但是,如果你想要为特定的键类型设置自己的哈希函数,你可以通过提供自己的哈希函数对象来实现。
相等的键,返回相等的哈希值,不相等返回不同的哈希值。
二.实例 std::unordered_map 与hash 实现 grid 二维表格
其中 grid 二维表格 也可以是其它对象
使用 std::unordered_map
和哈希函数来实现一个二维表格(grid)通常不是最直接或最高效的方法,因为 std::unordered_map
本质上是一个哈希表,其设计初衷是为了以常数平均时间复杂度快速查找、插入和删除键值对。二维表格通常更适合使用数组或二维数组(std::vector<std::vector<T>>
)来实现,因为它们在内存中是连续存储的,可以高效地访问任意位置的元素。
然而,如果你确实需要使用 std::unordered_map
来模拟一个二维表格,并且每个坐标点 (x, y) 是唯一的键,你可以将坐标点编码为一个键类型,并为这个键类型提供一个哈希函数。下面是一个简单的示例:
#include <iostream>
#include <unordered_map>
#include <functional> // for std::hash
#include <tuple> // for std::tuple
// 定义一个坐标点类型
struct Point {
int x;
int y;
// 提供相等性比较运算符
bool operator==(const Point& other) const {
return x == other.x && y == other.y;
}
};
// 为坐标点类型提供哈希函数
struct PointHash {
std::size_t operator()(const Point& p) const {
auto hasher = std::hash<int>{};
std::size_t h1 = hasher(p.x);
std::size_t h2 = hasher(p.y);
return h1 ^ (h2 << 1); // 或者使用其他组合方法
}
};
int main() {
// 使用自定义哈希函数的 unordered_map 来模拟二维表格
std::unordered_map<Point, int, PointHash> grid;
// 向表格中添加元素
grid[{0, 0}] = 1;
grid[{1, 0}] = 2;
grid[{0, 1}] = 3;
grid[{1, 1}] = 4;
// 访问表格中的元素
std::cout << "Value at (0, 0): " << grid[{0, 0}] << std::endl;
std::cout << "Value at (1, 1): " << grid[{1, 1}] << std::endl;
// 检查表格中是否存在某个坐标点
if (grid.find({0, 2}) != grid.end()) {
std::cout << "Point (0, 2) exists in the grid." << std::endl;
} else {
std::cout << "Point (0, 2) does not exist in the grid." << std::endl;
}
return 0;
}
在这个示例中,我们定义了一个 Point
结构体来表示二维坐标点,并为它提供了一个哈希函数 PointHash
。然后,我们使用 std::unordered_map<Point, int, PointHash>
来模拟二维表格,其中 Point
是键类型,int
是值类型,PointHash
是我们自定义的哈希函数。
虽然这个示例在技术上可行,但它并不是实现二维表格的最优方式。如果你需要频繁地访问表格中的元素,使用二维数组或 std::vector<std::vector<T>>
会更加高效。如果你需要处理稀疏表格(即大部分元素为空或默认值),那么 std::unordered_map
可能是一个合理的选择,因为它不会为未初始化的元素分配空间。然而,在这种情况下,你仍然需要仔细考虑坐标点的编码和哈希函数的实现,以确保性能和正确性。
文章绝大部分内容来在闻言一心!!!