C++ equivalent to Java Map getOrDefault?
C++ equivalent to Java Map getOrDefault?
Java的getOrDefault是一个很好的结构,用于一行访问映射值或起点(如果不存在(。 我在地图参考中没有看到任何内容C++与平行。 是否存在某些东西还是构建自己的东西?
我在地图中有对象,如果它们存在,我会更新它们,但如果它们不存在,我会构造新的对象。使用 getOrDefault,我可以在默认端构造对象,或者访问它(如果存在(。
http://www.cplusplus.com/reference/map/map/
https://www.geeksforgeeks.org/hashmap-getordefaultkey-defaultvalue-method-in-java-with-examples/
我在地图中有对象,如果存在,我会更新它们,但是 如果他们不这样做,则构建新的。使用 getOrDefault,我可以构造 对象,或者访问它(如果存在(。
使用emplace
.
auto& element = *map.emplace(key, value).first;
如果键不存在,emplace
插入一个新元素,并返回一对,该元素的迭代器(插入或已存在(和一个指示是否进行了插入的bool
值组成。
当我试图找出一种在C++中使用HashTable解决LeetCode单数问题的方法时,我来到了这里。
在方法 2 和 Java 中使用的 getOrDefault 没有直接的替代方案,但我能够使用 operator[] 来访问unordered_map的元素。 参见 http://www.cplusplus.com/reference/unordered_map/unordered_map/operator[]/
如果映射中存在该键,则运算符 [] 将返回对其映射值的引用。
如果键不存在,则运算符 [] 会将键添加到映射中,值为 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);
}
L.F 的答案是使用map::emplace
是映射的值类型不需要构造函数时要走的路,因为每次调用构造函数时都如下例所示。
C++17附带insert_or_assign
略有不同。
可能最有效的解决方案是执行以下操作:
template <class M, class Vp>
std::pair<typename M::iterator, bool> insert_or_create(M& map, typename M::key_type&& k, Vp&& v) {
auto p = map.lower_bound(k);
if (p != map.end()) {
return std::make_pair(p, false);
}
return std::make_pair(map.emplace_hint(p, std::move(k), std::forward<Vp>(v)), true);
}
下面是一个显示其工作原理的示例:
#include <sstream>
#include <iostream>
#include <string>
#include <map>
class Element {
public:
Element(int value) : value(value) {
std::cout << "Element ctor value = " + std::to_string(value) << std::endl;
}
int value;
};
template <class M, class Vp>
std::pair<typename M::iterator, bool> insert_or_create(M& map, typename M::key_type&& k, Vp&& v) {
auto p = map.lower_bound(k);
if (p != map.end()) {
return std::make_pair(p, false);
}
return std::make_pair(map.emplace_hint(p, std::move(k), std::forward<Vp>(v)), true);
}
int main(int argc, char **argv) {
std::map<int, Element> map;
auto& e1 = *map.emplace(1, Element(1)).first;
std::cout << "Element in map: " << std::to_string(e1.second.value) << std::endl;
auto& e11 = *map.emplace(1, Element(11)).first;
std::cout << "Element in map: " << std::to_string(e11.second.value) << std::endl;
auto e2 = *map.insert_or_assign(2, 2).first;
std::cout << "Element in map: " << std::to_string(e2.second.value) << std::endl;
auto e22 = *map.insert_or_assign(2, 22).first;
std::cout << "Element in map: " << std::to_string(e22.second.value) << std::endl;
auto e3 = *insert_or_create(map, 3, 3).first;
std::cout << "Element in map: " << std::to_string(e3.second.value) << std::endl;
auto e33 = *insert_or_create(map, 3, 33).first;
std::cout << "Element in map: " << std::to_string(e33.second.value) << std::endl;
}
产生
Element ctor value = 1
Element in map: 1
Element ctor value = 11 <-- calling ctor, not optimized away
Element in map: 1 <-- still old value in map as expected
Element ctor value = 2
Element in map: 2
Element ctor value = 22 <-- calling ctor
Element in map: 22 <-- new value assigned to key 2, as expected
Element ctor value = 3
Element in map: 3 <-- ctor not called as wanted!!!!!!
Element in map: 3
这表明insert_or_create
没有调用Element
的构造函数。
我不确定为什么这样的函数不在 std::map 接口中,因为它非常有用。
也许我误解了你在问什么,但这就是map
的工作方式。
map<int, string> m;
string s = m[3];
将s
设置为默认构造的string
。
当您使用operator[]
在地图中查找键时,它始终会返回一个值。如果映射中不存在该键,它将使用默认构造值插入它。
如果你想要这种行为,但使用不同的值(不是默认构造的值(,那么你可以使用emplace
,正如 L.F. 所建议的那样。
- 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;
我认为以下是您要查找的内容
mymap.emplace(key, DEFAULT_VALUE).first->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++;
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 使用一个考虑到std::map中键值的滚动或换行的键
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 允许从 std::map 的密钥窃取资源?
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将重物插入std::map
- 使用通用值初始化 std::map,不重复
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- C++:当所有条目都保证是唯一时,替代 std::map
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- 使用字符数组作为 Map 中的键
- C++如何创建 std::map
- C++ equivalent to Java Map getOrDefault?
- 从其他容器中移动构造"std::map"
- 如何使用 uint64_t 键类型从 std::map<int, std::string> 返回值?
- 将 std::map::emplace 与返回 shared_ptr 的函数一起使用是否正确?
- C++中 std::map 的运行时复杂度是多少?
- 为什么在 std::map 上移动无法将元素从一个映射移动到另一个映射