使用 std:::明智地与现代C++
std::地图和它的兄弟姐妹(std::多映射,std::unordered_m … Read More
Socrates
std::地图和它的兄弟姐妹(std::多映射,std::unordered_map/多映射)曾经是我最喜欢的容器,当我做竞争编程。事实上,我仍然喜欢它们(尽管现在使用频率较低)。随着现代C++,我们现在有更多的理由使用std:地图。因此,我决定写一篇总结这些新功能的文章来讨论这个话题。所以,没有太多的胡言乱语,让我们直接潜入。
std::地图::包含(C++20)
std::map::contains成员函数是走向代码表达性的好一步。我也厌倦了写作:
cout<<"Found"<<endl;
}
假设为 freq_of = 映射<uint32_t,uint32_t>{3, 1},{1, 1},{2},1];
相反,从 C++20 开始,您可以编写:
x
如果(freq_of。包含(2)|
cout<<"Found"<<endl;
}
我们编写的代码是先为人类消费而编写的,其次为计算机所编写的。
– 约翰·桑梅斯
std::地图::try_emplace (C++17)
在插入地图时,我们有两种不同的可能性:
- 密钥尚不存在。创建新的键值对。
- 密钥确实存在。拿现有项目并修改它。
插入元素的典型方法
std::map是通过使用
operator[ ],
std::map::insert或
std::map::emplace .但是,在所有这些情况下,我们必须承担默认/专用构造函数或赋值调用的成本。最糟糕的是,如果一个项目已经存在,我们必须删除新创建的项。
X
int主() |
矢量 v=345873524+;
地图<uint32_tuint32_tuint32_t>freq_of;
用于(const自动&nv) |
如果(康斯特自动&=它插入=freq_offreq_of。位置(n1!插入){
它->第二 =; // 已存在
}
}
12返回EXIT_SUCCESS;
}
相反
X
如果(康斯特自动&=它插入=freq_offreq_of。try_emplace(n1!插入){
它->第二 =;
}
但是,C++17,有这个
std::try_emplace:::仅在键尚不存在时创建项的方法。这会提高性能,以防创建此类对象的成本很高。
std::map::try_emplace.
std::地图::insert_or_assign (C++17)
无论如何,当您必须插入元素时。为了方便起见,您使用
std::地图::运算符=。这是确定(和
危险)!除非对插入或赋值有任何限制
e. 已分配),您必须删除所有小于当前元素的元素。
std::map::operator[ ]是不可行的。而std::map::insert_or_assign 比 更合适,返回的信息比 std::map::operator[ ] 更多。它也不要求映射类型的默认构造性。请考虑以下示例。
x
矢量 v=83958+;
地图<uint32_tuint32_tuint32_t>freq_of;
用于(自动 &nv) |
康斯特自动&is_insertedis_inserted=freq_of。insert_or_assign(n1);
freq_of.擦除(开始)freq_of它);
}
}
断言((freq_of=decltype(freq_of)
[81],
16
}));
17
18
返回EXIT_SUCCESS;
19
}
std::地图::插入带提示 (C++11/17)
在
std::map采取
O(log(n))时间。对于插入新项目,这是相同的。因为插入它们的位置必须向上。天真地插入
M因此,新项目将采取
O(M * log(n))时间。
为了提高效率,
std::map插入函数接受可选的插入提示参数。插入提示基本上是一个活动器,它指向要插入的项目的未来位置附近。如果提示是正确的,那么我们得到摊销
O(1)插入时间。
从性能的角度来看,当项的插入顺序有些可预测时,这非常有用。例如:
Java