C ++映射冲突解析为java HashMap

时间:2014-02-17 09:28:12

标签: java c++ collections

我已经在使用Hashmap的java中运行,良好而快速的算法。

Hashmap<Point, Float>map; //point object as a key. no nulls objects in key and values

Point类具有以下结构

static public class Point {
    private int x;
    private int y;

    int hashCode() {
     int hash = 5;
     hash = 59 * hash + this->x;
     hash = 59 * hash + this->y;
     return hash;
    }
    boolean equals(Point p){
     return x==p.x&&y==p.y;
    }
}

我应该在c ++中重新实现我的算法。 我决定使用c ++ stl hashmap。

我根据c ++语法简单地复制了Point类,并按照以下方式编写了map:

std::map<long, float>mymap;//key-hashcode of the point
mymap[point.hashcode()]=45;//example of using

但我发现,有时c ++版本的算法会返回错误的结果。经过大量的调试,我发现,有些点会返回相同的哈希码:

Point(8,89).hashcode()==17966; //x=8,y=89
Point(9,30).hashcode()==17966; //x=9,y=30

java Hashmap使用hashmap中的equals函数解决这个冲突作为哈希冲突解决方案,但我不知道,如何在c ++中实现这个... 可能是我应该写出更好的哈希函数,但我认为这不会完全解决我的问题,只能删除一些碰撞,但会创建新的。 你能救我吗?

UPD:

将以下代码添加到Point类:

bool operator <(const Point& rhs) const
{
    return getX()<rhs.getX()|| (!(rhs.getX()<getX()) && getY()<rhs.getY()); 
}

并声明地图如下:

std::map<Point, float>mymap;

并且所有都开始按预期工作

3 个答案:

答案 0 :(得分:4)

与Java一样,您应该使用Points作为键而不是Points的哈希码:

std::map<pair<long, long>, float>mymap;
mymap.insert(std::make_pair(8,89), 0.1);

结构pair非常适合表示一个简单的点,它会重载map用于定位键的所有比较operators

您可能希望键入对该对进行设置,以便更清楚地了解地图中存储的内容:

typedef pair<long, long> Point;

答案 1 :(得分:1)

的std ::地图&LT;&GT;不是HashTable地图,它是一张树形图。有hash_map类,但它还没有在C ++ Standard中。见Is hash_map part of the STL?

答案 2 :(得分:0)

从c ++ 11开始,你可以使用std :: unordered_map,下面就是一个简单的例子。您在c ++中的Java equals方法是bool Point::operator==

http://coliru.stacked-crooked.com/a/1260a66b7f350816

#include <iostream>
#include <unordered_map>

struct Point
{
  Point(int px, int py) : x(px), y(py) {}
  int x,y;

  bool operator==(const Point &other) const
  { return (x == other.x
            && y == other.y);
  }
};

namespace std {
  template <>
  struct hash<Point>
  {
    std::size_t operator()(const Point& k) const
    {
      return (k.x + k.y); // silly function, just to produce equal hashes below
    }
  };
}
int main()
{
   std::unordered_map<Point,std::string> mmap = {
    { {0,1}, "example"},
    { {1,0}, "another"}
   };   
   std::cout << mmap.size() << std::endl;   // outputs 2

   std::unordered_map<Point,std::string> mmap2 = {
    { {0,1}, "example"},
    { {0,1}, "another"}
   };   
   std::cout << mmap2.size() << std::endl;   // outputs 1
   return 0;
}