首先,我为operator==
和专门的Point2D
模板类定义了struct hash<Point2D>
,以便在它们位于同一行时能够考虑非唯一的点。
在下面的代码中,我在同一行生成1000个随机点并检查它们是否相等,我打印is equal: 1
1000
次,但最后,它被打印2当我试验hash
函数并返回任何注释值时,unordered_set
的大小变为1(即使我在哈希函数中返回一个const数)。那么下面我的哈希函数出了什么问题?
#include <cmath>
#include <algorithm>
#include <numeric>
#include <vector>
#include <iostream>
#include <set>
#include <string>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <limits>
#include <functional>
#include <stack>
#include <queue>
#include <random>
using namespace std;
struct Point2D
{
int x;
int y;
bool operator==(const Point2D& other) const
{
return x * other.y == y * other.x;
}
};
namespace std
{
template <>
struct hash<Point2D>
{
std::size_t operator()(const Point2D& k) const
{
// Compute individual hash values for first,
// second and combine them using XOR
// and bit shifting:
return ((hash<int>()(k.x) ^ (hash<int>()(k.y) << 1)) >> 1);
/*
int i1 = k.x;
int i2 = k.y;
size_t ret = i1;
ret *= 2654435761U;
return ret ^ i2;
*/
/*
return 111;
*/
}
};
}
int solution(vector<Point2D> &A)
{
unordered_set<Point2D> pointsOnTheSameLine;
for (auto& point : A)
{
pointsOnTheSameLine.insert(point);
}
return static_cast<int>(pointsOnTheSameLine.size());
}
int main()
{
std::random_device rd; // only used once to initialise (seed) engine
std::mt19937 rng(rd()); // random-number engine used (Mersenne-Twister in this case)
std::uniform_int_distribution<int> uni(-10000, 10000); // guaranteed unbiased
int x = 13;
int y = 7;
vector<Point2D> v; // { {0, 1}, {0, 2}, {1, 1}, {-1, -1} };
for (int i = 0; i < 1000; ++i)
{
auto random_integer = uni(rng);
const Point2D curr{x * random_integer, y * random_integer};
v.push_back(curr);
cout << "is equal: " << (Point2D{x, y} == curr) << endl;
}
cout << solution(v) << endl;
return 0;
}
散列函数如何影响结果。它会影响我的程序运行的时间,因为根据哈希函数可能会有大量或小量的冲突,但是我的程序应该返回相同的结果,对吧?
答案 0 :(得分:4)
我希望获得
operator==
,因为根据==
所有生成的点数相等
根据operator==
的等同性不足以使哈希容器认为所有点都相等:哈希函数也必须为被认为相等的点返回相同的值。当哈希值不同时,无序容器甚至不会将gcd
应用于存储的值,从而产生您看到的结果。
实现这一目标的一种方法是通过除以int gcd (int a, int b){
a = abs(a); b = abs(b);
return (b==0) ? a : gcd(b, a%b);
}
std::size_t operator()(const Point2D& k) const {
int g = gcd(k.x, k.y);
int a = k.x/g, b = k.y/g;
return a ^ b;
}
来计算斜率,并用分母对分子进行xor:
public static void main(String[] args) {
try{
System.out.println("This is try block...!!");
}
catch(Exception e)
{
System.out.println("Exception is "+e);
}
finally
{
System.exit(0);//terminates finally block
System.out.println("This is finally block");
}
System.out.println("This is outside the try catch block...");
}
答案 1 :(得分:0)
问题可能是某些相等的点(对于Point2D :: operator ==是正确的)会在代码中产生不同的哈希值。
等分点应产生相同的哈希值。