【问题标题】:How to change the key in an unordered_map?如何更改 unordered_map 中的键?
【发布时间】:2018-09-25 05:25:04
【问题描述】:

我需要使用平均支持恒定时间查找的数据结构。我认为使用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 以外的其他数据结构?

【问题讨论】:

    标签: c++ algorithm unordered-map


    【解决方案1】:

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

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

    【讨论】:

    • 平均时间通常用 theta (Θ) 表示,而不是 big-oh
    • 没有。在最好和最坏的情况下,Big Theta 都用于严格限制的时间;它不适用于 O(1) != O(n)。
    【解决方案2】:
    #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
        }
    }
    

    【讨论】:

      【解决方案3】:
      #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);
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-19
        • 1970-01-01
        相关资源
        最近更新 更多