通过给定点的最小行数

时间:2018-04-10 12:08:18

标签: c++ algorithm hash unordered-set

首先,我为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;
}

散列函数如何影响结果。它会影响我的程序运行的时间,因为根据哈希函数可能会有大量或小量的冲突,但是我的程序应该返回相同的结果,对吧?

2 个答案:

答案 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...");
}

here

答案 1 :(得分:0)

问题可能是某些相等的点(对于Point2D :: operator ==是正确的)会在代码中产生不同的哈希值。

等分点应产生相同的哈希值。