我已经在使用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;
并且所有都开始按预期工作
答案 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;
}