通过给定点的最小线数
Minimum count of lines that goes through the given points
首先,我已经为 Point2D
定义了 operator==
并专门化了 struct hash<Point2D>
模板 class 以便能够将位于同一行上的点视为非唯一点.
在下面的代码中,我在同一行上生成了 1000 个随机点,并检查它们是否相等,然后我打印了 is equal: 1
1000
次,但最后,它被打印 2. 当我试验 hash
函数和 return 任何注释值时,unordered_set
的大小变为 1(即使我 return哈希函数)。那么我下面的哈希函数有什么问题?
#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;
}
哈希函数如何影响结果。它会影响我的程序运行时间,因为根据散列函数的不同,可能会有或大或小的冲突,但我的程序应该 return 相同的结果,对吧?
问题可能在于某些相等的点(Point2D::operator== 为真)在您的代码中产生了不同的哈希值。
相等的点应产生相同的哈希值。
I expect to get 1
, as according the my operator==
all the generated points are equal
根据 ==
的相等性不足以让散列容器认为所有点都相等:散列函数还必须 return 相同的点值被认为是相等的。当哈希值不同时,无序容器甚至不会将您的 operator==
应用于存储的值,这会导致您看到的结果。
实现此目的的一种方法是通过除以 gcd
和 xor-ing 分子与分母来计算斜率:
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;
}
首先,我已经为 Point2D
定义了 operator==
并专门化了 struct hash<Point2D>
模板 class 以便能够将位于同一行上的点视为非唯一点.
在下面的代码中,我在同一行上生成了 1000 个随机点,并检查它们是否相等,然后我打印了 is equal: 1
1000
次,但最后,它被打印 2. 当我试验 hash
函数和 return 任何注释值时,unordered_set
的大小变为 1(即使我 return哈希函数)。那么我下面的哈希函数有什么问题?
#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;
}
哈希函数如何影响结果。它会影响我的程序运行时间,因为根据散列函数的不同,可能会有或大或小的冲突,但我的程序应该 return 相同的结果,对吧?
问题可能在于某些相等的点(Point2D::operator== 为真)在您的代码中产生了不同的哈希值。
相等的点应产生相同的哈希值。
I expect to get
1
, as according the myoperator==
all the generated points are equal
根据 ==
的相等性不足以让散列容器认为所有点都相等:散列函数还必须 return 相同的点值被认为是相等的。当哈希值不同时,无序容器甚至不会将您的 operator==
应用于存储的值,这会导致您看到的结果。
实现此目的的一种方法是通过除以 gcd
和 xor-ing 分子与分母来计算斜率:
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;
}