如何在unordered_map中更改密钥?

How to change the key in an unordered_map?

本文关键字:密钥 map unordered      更新时间:2023-10-16

我需要使用平均支持恒定时间查找的数据结构。我认为使用std::unordered_map是一个很好的方法。我的数据是数字的"集合"。

|115|190|380|265|

这些数字不必按特定顺序排列。我需要大约O(1)时间来确定此数据结构中是否存在给定的数字。我有使用std::unordered_map的想法,它实际上是一个哈希表(我说得对吗?所以数字将是键,然后我只有虚拟值。

所以基本上我首先需要确定数据结构中是否存在与给定数字匹配的键,然后我根据该条件运行一些算法。除了该条件之外,我还想更新特定密钥。假设190,我想在其中添加20,所以现在密钥将是210。 现在数据结构如下所示:

|115|210|380|265|

我想这样做的原因是因为我有一个遍历二叉搜索树的递归算法。每个节点都有一个int value,以及两个指向左右节点的指针。当到达叶节点时,我需要在保存current_node->value的"哈希表"数据结构中创建一个新字段。然后,当我在递归中返回树时,我需要连续将节点的每个值添加到存储在键中的先前总和中。我的数据结构(我建议应该是std::unordered_map(有多个数字字段的原因是因为它们中的每一个都代表从树上的叶节点到中间某个节点的唯一路径。我检查从叶子上升到给定节点的路径上所有节点值的总和是否等于该节点的值。所以基本上在每个键中添加节点的当前值,存储该路径上所有节点的总和。我需要扫描该数据结构以确定任何一个字段或键是否等于当前节点的值。我还想在接近恒定的时间内将新值插入到数据结构中。这是为了竞争性编程,我会犹豫是否使用std::vector因为我认为查找元素并插入元素需要线性时间。这会搞砸我的时间复杂性。也许我应该使用除std::unordered_map以外的其他数据结构?

您可以使用 unordered_map::erase 和 unordered_map::insert 来更新密钥。平均时间复杂度为 O(1((顺便说一句,最差的是 O(n((。如果您使用的是 C++17,则还可以使用 unordered_map::extract 来更新密钥。时间复杂度是相同的。

但是,由于您只需要一组数字,因此我认为unordered_set更适合您的算法。

#include <unordered_map>
#include <iostream>
int main()
{
std::unordered_map<int, int> m;
m[42];  // add
m[69];  // some
m[90];  // keys
int value = 90;  // value to check for
auto it = m.find(90);
if (it != m.end()) {
m.erase(it);      // remove it
m[value + 20];    // add an altered value
}
}
#include <unordered_map>
#include <string>
int main() {
// replace same key but other instance
std::unordered_map<std::string, int> eden;
std::string k1("existed key");
std::string k2("existed key");
const auto &[it, first] = eden.try_emplace(k1, 1);
if (!first) {
eden.erase(it);
eden.emplace_hint(it, k2, 123);
}
}

从 C++17 开始,您还可以按如下方式使用其extract函数:

std::unordered_map<int, int> map = make_map();
auto node = map.extract(some_key);
node.key() = new_key;
map.insert(std::move(node));