【问题标题】:Why does += work on std::map keys that don't have values?为什么 += 对没有值的 std::map 键起作用?
【发布时间】:2017-03-16 13:23:40
【问题描述】:

我在看人家解决问题的方法here

给定一个由开始和结束时间组成的会议时间间隔数组 [[s1,e1],[s2,e2],...] (si

其中一个解决方案是执行以下操作:

#include <map>
#include <vector>
#include <algorithm>

using std::max;
using std::map;
using std::vector;

struct Interval {
  int start;
  int end;
  Interval() : start(0), end(0) {}
  Interval(int s, int e) : start(s), end(e) {}
};

int minMeetingRooms(vector<Interval>& intervals) {
    map<int, int> changes;
    for (auto i : intervals) {
      changes[i.start] += 1;
      changes[i.end] -= 1;
    }
    int rooms = 0, maxrooms = 0;
    for (auto change : changes)
      maxrooms = max(maxrooms, rooms += change.second);
    return maxrooms;
}

每次新会议开始时增加一个计数器,每次会议结束时减少一个计数器,取该计数器的最大值和每次迭代的前一个最大值。


我很好奇的是地图初始化的部分

for (auto i : intervals) {
  changes[i.start] += 1;
  changes[i.end] -= 1;
}

地图中的值从未设置过,但您仍然可以使用+= 运算符。我假设这会导致地图在那个地方创建一个0,然后你会增加它,但这是未定义的行为吗?每种类型都有默认值吗?例如,如果我有一张&lt;int, string&gt; 的地图,它会将什么作为默认值?它只是调用默认构造函数吗?

基本上我想知道的是std::map 的内部结构,它允许添加到一个尚不存在的键,以及它如何因类型而异。


附注:

如果我想写更多地道的代码,我会放

if (changes.find(i.start) == changes.end()) changes[i.start] = 0
if (changes.find(i.end) == changes.end()) changes[i.end] = 0

但我猜这是性能下降还是什么?

【问题讨论】:

    标签: c++ c++11 dictionary stl


    【解决方案1】:

    阅读the docs

    返回对映射到与 key 等效的键的值的引用,如果这样的键不存在,则执行插入。

    插入只是使用key的默认构造函数,int的默认构造函数生成0。

    您的“更惯用”的代码与惯用语完全相反。当你想要自动激活时使用operator[],当你试图避免自动激活时你只使用count/find

    如果您来自 Python 背景,这可能看起来倒退,但它是惯用的 C++。 C++ std::map 的行为更像 Python defaultdict 而不是 dict;运算符查找自动激活,避免自动激活需要显式方法调用。

    【讨论】:

    • 好的,谢谢!我以为我遗漏了一些东西,我很高兴你评论了我的“更惯用”的想法在这种情况下是如何错误的。欣赏!
    • @AR7:很高兴它有帮助。这种方法在 C++ 中比在 Python 中更有意义,因为 C++ 无论如何都有值的静态类型,所以它总是知道应该存在什么。 Python 的动态类型意味着它通常不具备该知识(值可以是任何类型,因此自动激活没有意义)。
    猜你喜欢
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 2014-08-06
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多