如何实现不区分端点顺序的segment类正确哈希(hash)函数?
线段类无顺序敏感哈希实现方案
现有实现的隐患
你当前使用按位或|合并两种端点顺序哈希值的实现存在明显缺陷:
- 按位或操作会丢失大量位特征,只要两个哈希值任意一个对应位为1,结果位就为1,会大幅提升哈希冲突概率,不同线段很容易得到相同的哈希值,导致
set()存储时出现误判。 - 未保证哈希逻辑和
__eq__逻辑对齐,如果你的__eq__方法没有实现不区分端点顺序的相等判断,即使哈希正确,set()的去重逻辑也会失效。
最优稳妥实现方案(优先正确性)
核心思路是:将两个端点强制转换为固定排序的有序对,再对有序对做哈希,完全规避顺序影响,哈希冲突概率和普通有序对象完全一致。
你可以二选一即可:
方案1:基于端点坐标排序(最稳妥,不依赖point类的哈希实现)
先对两个端点的坐标做大小比较,确定固定顺序后生成有序元组再哈希:
def __hash__(self): """ 返回不区分端点顺序的线段哈希值 """ # 按x→y的优先级排序两个端点 if (self.p0.x, self.p0.y) < (self.p1.x, self.p1.y): sorted_points = (self.p0, self.p1) else: sorted_points = (self.p1, self.p0) return hash(sorted_points)
方案2:基于端点哈希值排序(实现更简洁,依赖point类哈希正确性)
如果你的point类的哈希实现已经稳定(你给出的实现是没问题的),可以直接对两个端点的哈希值排序后计算哈希:
def __hash__(self): """ 返回不区分端点顺序的线段哈希值 """ h0, h1 = hash(self.p0), hash(self.p1) return hash((h0, h1) if h0 < h1 else (h1, h0))
必须配套的相等判断实现
哈希逻辑必须和__eq__逻辑完全对齐,你需要同步修改segment类的__eq__方法,实现不区分端点顺序的相等判断:
def __eq__(self, other): if not isinstance(other, segment): return False return (self.p0 == other.p0 and self.p1 == other.p1) \ or (self.p0 == other.p1 and self.p1 == other.p0)
内容的提问来源于stack exchange,提问作者senseiwa
相关产品推荐
相关产品推荐

