【问题标题】:C++ equivalent to Java Map getOrDefault?C++ 等价于 Java Map getOrDefault?
【发布时间】:2020-02-07 04:23:22
【问题描述】:

Java 的 getOrDefault 是一个很好的构造,用于单行访问地图值或起点(如果不存在)。我在 C++ 中的地图参考中没有看到任何平行的东西。有什么东西存在还是你自己建立的?

我在地图中有对象,如果它们存在我会更新它们,但如果它们不存在则构建新对象。使用 getOrDefault,我可以在默认端构造对象,或者在它存在时访问它。

http://www.cplusplus.com/reference/map/map/

https://www.geeksforgeeks.org/hashmap-getordefaultkey-defaultvalue-method-in-java-with-examples/

【问题讨论】:

  • 您要返回引用还是值?
  • 这里是同样的问题stackoverflow.com/questions/45389872/… 除了默认是可选的
  • map.at() 函数将在未找到该项目时抛出异常。但是 map [] 运算符插入一个默认构造值,如果它不存在并返回它。因此,您可能想要auto v = (m.find(k)!=m.end()?m[k]:"default"),但与 elvis 运算符相比,它长得可笑而且复杂。
  • 我应该多说一下我的预期用途。我在地图中有对象,如果它们存在我会更新它们,但如果它们不存在则构建新对象。使用 getOrDefault,我可以在默认端构造对象,或者在它存在时访问它。
  • 我从不想要一个可选项,我要么想要一个新构造的对象,并根据当前情况传递一些参数,要么想要一个已经在地图中的对象。

标签: c++ c++17 treemap


【解决方案1】:

我在地图中有对象,如果它们存在我会更新它们,但是 如果没有,则构建新的。使用 getOrDefault,我可以构建 默认端的对象,如果存在则访问它。

使用emplace

auto& element = *map.emplace(key, value).first;

emplace 如果键不存在,则插入一个新元素,并返回一个由指向该元素(已插入或已存在)的迭代器和指示是否插入的 bool 值组成的对。

【讨论】:

  • 谢谢,这就是我正在寻找的功能。它盯着我的脸,我错过了。
  • @Evan 这真的是你想要的吗? getOrDefault 是get or 默认,不是get 还是insert-and-then-get?也就是说,getOrDefault 永远不会插入到地图中。
  • @Barry,这是绝对正确的,但在这种情况下,我的意图是插入我在地图中构建的对象,如果它不存在并更新它。获取引用以及指示它是否存在的布尔值允许我做我想做的事。无论如何,这是我最常见的 getOrDefault 用例。
【解决方案2】:

当我试图找出在 C++ 中使用 HashTable 解决 LeetCode 单数问题的方法时,我来到了这里。

没有直接替代方法 2 和 Java 中使用的 getOrDefault,但我能够使用 operator[] 访问 unordered_map 的元素。 见http://www.cplusplus.com/reference/unordered_map/unordered_map/operator[]/

如果映射中存在键,则 operator[] 将返回对其映射值的引用。

如果 key 不存在,则 operator[] 会将 key 添加到 map 中,值为 0。

当您尝试增加一个键的值(如果它已经存在)或向映射添加一个新键(如果它不存在)时,这可能很有用。

例如,我在 C++ 中使用了以下代码

for (int i : nums) { hash_table[i] = hash_table[i] + 1; }

这是Java中以下内容的替代方法

for (int i : nums) { hash_table.put(i, hash_table.getOrDefault(i, 0) + 1); }

【讨论】:

    【解决方案3】:

    也许我误解了你在问什么,但这就是map 的工作原理。

    map<int, string> m;
    string s = m[3];
    

    会将s 设置为默认构造的string

    当您使用operator[] 在地图中查找键时,它总是会返回一个值。如果映射中不存在该键,它将插入它,并使用默认构造值。

    如果您想要这种行为,但使用不同的值(不是默认构造的值),那么您可以使用 emplace,正如 L.F. 所建议的那样。

    【讨论】:

    • 对,我需要一些不是默认构造的东西。 L.F. 的答案正是我想要的。
    【解决方案4】:
    • Java
    
        map.put(sum, map.getOrDefault(value, 0) + 1);
    
    
    • c++ 中的等效代码
    
        auto it1 = map.find(value);
        if (it1 != um.end())
            map[value]++;
        else
            map[value] = 1;
    

    【讨论】:

      【解决方案5】:

      我认为下面是您正在寻找的内容

      mymap.emplace(key, DEFAULT_VALUE).first-&gt;second = value;

      就像在下面的示例中使用的那样

          #define DEFAULT_VALUE 0
          map<int,int> mymap;
          mymap[1] = 1;
          // mymap is having some entries.
      
          // will increment existing element.
          mymap.emplace(1,DEFAULT_VALUE).first->second++; 
      
          // will insert a new element with key 2 and value as default(0), than increment it.
          mymap.emplace(2,DEFAULT_VALUE).first->second++; 
      

      【讨论】:

        猜你喜欢
        • 2018-01-25
        • 1970-01-01
        • 2011-09-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-01
        • 2013-10-09
        • 2013-05-26
        • 2010-10-04
        相关资源
        最近更新 更多