散列2D点的有效方法

时间:2014-10-05 20:22:56

标签: c++ optimization hash map

好的,所以任务就是这个,我将得到(x,y)点的坐标,其中(x,y)的范围从-10 ^ 6到10 ^ 6(含)。我必须检查一个特定点,例如(x,y)元组是给我的还是没有。简单来说,我如何回答查询是否设置了特定点(2D)。到目前为止,我能想到的最好的是保持一个std::map<std::pair<int,int>, bool>,每当给出一个点我就标记它1.虽然这必须以对数时间运行并且是一种相当优化的方式来回答查询我想知道是否有&# 39;这是一个更好的方法。

如果我使用上述数据结构作为哈希,我会很高兴有人能说出实际的复杂性。我的意思是std::map的复杂性将是O(log N )无论关键结构如何,存在的元素大小?

2 个答案:

答案 0 :(得分:4)

不是将每个点映射到bool,为什么不将所有给出的点存储在一个集合中呢?然后,您只需搜索该集合,查看它是否包含您要查找的点。它与您正在执行的操作基本相同,而无需对关联的bool进行额外查找。例如:

set<pair<int, int>> points;

然后,您可以检查该集合是否包含某个点,如下所示:

pair<int, int> examplePoint = make_pair(0, 0);
set<pair<int, int>>::iterator it = points.find(examplePoint);

if (it == points.end()) {
    // examplePoint not found
} else {
    // examplePoint found
}

如上所述,std::set通常作为平衡二叉搜索树实现,因此每次查找都需要O(logn)时间。

如果您想使用哈希表,则可以使用std::unordered_set而不是std::set执行相同的操作。假设您使用了良好的哈希函数,这将使您的查找速度提高到O(1)时间。但是,为此,您必须为pair<int, int>定义哈希函数。以下是this回答中的示例:

namespace std {
template <> struct hash<std::pair<int, int>> {
    inline size_t operator()(const std::pair<int, int> &v) const {
        std::hash<int> int_hasher;
        return int_hasher(v.first) ^ int_hasher(v.second);
    }
};

}

编辑:没关系,我看到你已经开始工作了!

答案 1 :(得分:2)

要使用哈希地图,您需要使用std::unordered_map而不是std::map。使用它的约束是你的值类型需要有一个为它定义的哈希函数,如in this answer所述。要么是这样,要么只使用boost::hash

std::unordered_map<std::pair<int, int>, boost::hash<std::pair<int, int> > map_of_pairs;

另一种让人想到的方法是将32位int值存储在64位整数中,如下所示:

uint64_t i64;
uint32_t a32, b32;
i64 = ((uint64_t)a32 << 32) | b32;

this answer所述。 x和y组件可以存储在整数的高字节和低字节中,然后您可以使用std::unordered_map<uint64_t, bool>。虽然我有兴趣知道这是否比以前的方法更有效,或者它是否产生不同的代码。