C++ C++;在无序对中存储值

C++ C++;在无序对中存储值,c++,arrays,unordered-map,unordered-set,unordered,C++,Arrays,Unordered Map,Unordered Set,Unordered,我想为一对无序的整数存储一个浮点值。我找不到任何简单易懂的教程。例如,对于无序对{i,j}我想存储一个浮点值f。如何插入、存储和检索这样的值?以下是一些指示代码: #include <iostream> #include <unordered_map> #include <utility> struct Hasher { int operator()(const std::pair<int, int>& p) const

我想为一对无序的整数存储一个浮点值。我找不到任何简单易懂的教程。例如,对于无序对
{i,j}
我想存储一个浮点值
f
。如何插入、存储和检索这样的值?

以下是一些指示代码:

#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';
}

在电视上看。如果你想做一个更好的散列函数,只需找到一个
hash\u combine
(或使用boost)的实现——这里有很多问题,解释一下如何为
std::pair
s实现它。

你实现了一个带有你的需求的类型UPair,并重载
::std::hash
(这是极少数允许您在
std
中实现某些功能的情况)

#包括
#包括
模板
上等舱{
私人:
::std::对p;
公众:
上行(TA,TB):p(::标准::最小(a,b),::标准::最大(a,b)){
}   
UPair(::std::pair pair):p(::std::min(pair.first,pair.second),::std::max(pair.first,pair.second)){
}   
友元布尔运算符==(上风常数和a、上风常数和b){
返回a.p==b.p;
}   
运算符::std::pair()常量{
返回p;
}   
};
名称空间标准{
模板
结构散列{
::std::size\u t运算符()(向上常量和向上常量){
return::std::hash()(
::std::hash()(::std::pair(up).first)
) ^
::std::hash()(::std::pair(up).second);
//双哈希是为了避免在.first和.second中具有相同的值,从而导致始终为0
//这将是无序地图性能的一个问题
}   
};  
}
int main(){
::std::无序地图um;
um[UPair(3,7)]=3.14;
um[UPair(8,7)]=2.71;
返回10*um[::std::make_pair(7,3)];//正确返回31
}

处理无序整数对的简单方法是使用
std::minmax(i,j)
生成
std::pair
。这种方法可以实现如下存储:

   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)]
std::地图存储;
储存量[std::minmax(i,j)]=0.f;
存储器[std::minmax(j,i)]=1.f;//重写存储器[(i,j)]

诚然,适当的散列会给您带来一些额外的性能,但是推迟这种优化没有什么害处。

您需要为要用作键的类型专门化
std::hash
,并且还需要在其上定义
operator==
。就是这样。
std::map
应该可以在没有专门化的情况下工作你的意思是{1,2}和{2,1}被认为是相同的吗?@JonathanPotter要使用
std::map
,用户必须定义自己的散列function@hoder映射使用更少,而不是散列
#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
}
   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)]