C++将一个值存储在无序对中
C++ storing a value in an unordered pair
我想为一对无序的整数存储一个浮点值。我找不到任何易于理解的教程。例如,对于无序对{i,j}
,我想存储一个浮点值f
。如何像这样插入、存储和检索值?
std::minmax(i,j)
生成std::pair<int,int>
。通过这种方式,您可以像这样实现存储: std::map<std::pair<int,int>,float> storage;
storage[std::minmax(i,j)] = 0.f;
storage[std::minmax(j,i)] = 1.f; //rewrites storage[(i,j)]
诚然,适当的哈希会给你带来一些额外的性能,但推迟这种优化并没有什么害处。
这里有一些指示性代码:
#include <iostream>
#include <unordered_map>
#include <utility>
struct Hasher
{
int operator()(const std::pair<int, int>& p) const
{
return p.first ^ (p.second << 7) ^ (p.second >> 3);
}
};
int main()
{
std::unordered_map<std::pair<int,int>, float, Hasher> m =
{ { {1,3}, 2.3 },
{ {2,3}, 4.234 },
{ {3,5}, -2 },
};
// do a lookup
std::cout << m[std::make_pair(2,3)] << 'n';
// add more data
m[std::make_pair(65,73)] = 1.23;
// output everything (unordered)
for (auto& x : m)
std::cout << x.first.first << ',' << x.first.second
<< ' ' << x.second << 'n';
}
请注意,它依赖于先存储具有较低数字的无序对的约定(如果它们不相等)。您可能会发现编写一个支持函数很方便,该函数接受一对并按顺序返回,因此在映射中插入新值时以及在映射中使用一对作为尝试查找值的键时,都可以使用该函数。
输出:
4.234
3,5 -2
1,3 2.3
65,73 1.23
2,3 4.234
请在ideone.com上查看。如果你想制作一个更好的哈希函数,只需查找hash_combine
的实现(或使用boost)-SO上有很多问题解释了如何为std::pair<>
s做到这一点。
您根据自己的需求实现了一个类型UPair,并重载了::std::hash
(这是允许您在std
中实现某些东西的罕见情况)。
#include <utility>
#include <unordered_map>
template <typename T>
class UPair {
private:
::std::pair<T,T> p;
public:
UPair(T a, T b) : p(::std::min(a,b),::std::max(a,b)) {
}
UPair(::std::pair<T,T> pair) : p(::std::min(pair.first,pair.second),::std::max(pair.first,pair.second)) {
}
friend bool operator==(UPair const& a, UPair const& b) {
return a.p == b.p;
}
operator ::std::pair<T,T>() const {
return p;
}
};
namespace std {
template <typename T>
struct hash<UPair<T>> {
::std::size_t operator()(UPair<T> const& up) const {
return ::std::hash<::std::size_t>()(
::std::hash<T>()(::std::pair<T,T>(up).first)
) ^
::std::hash<T>()(::std::pair<T,T>(up).second);
// the double hash is there to avoid the likely scenario of having the same value in .first and .second, resulinting in always 0
// that would be a problem for the unordered_map's performance
}
};
}
int main() {
::std::unordered_map<UPair<int>,float> um;
um[UPair<int>(3,7)] = 3.14;
um[UPair<int>(8,7)] = 2.71;
return 10*um[::std::make_pair(7,3)]; // correctly returns 31
}
相关文章:
- 将字符串存储在c++中的稳定内存中
- std::原子加载和存储都需要吗
- C++:将控制台输出存储在宏中更好吗
- 使用QProcess执行命令,并将结果存储在QStringList中
- 访问存储在向量C++中的结构的多态成员
- 如何从存储在std::映射中的std::集中删除元素
- 递归无序映射
- 存储模板类型以强制转换回派生<T>
- 类型总是使用其大小存储在内存中吗
- 当字符串存储在变量中时,如何将字符串转换为wchar_t
- 使用无符号字符数组有效存储内存
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- 将大数字(10-12 位数字)存储在无序映射中<字符串,整数>
- 使用无序映射在STL中存储键值对
- 将大型对象存储在无序映射中是否效率低下
- 无序映射存储桶的节点大小
- C++将一个值存储在无序对中
- 如何在一个无序映射中存储2个以上的变量
- C++将类的静态方法存储在无序映射中
- 如何调整无序STL容器以仅存储键值对的值