在CPython中如何实现Frozenset相等性?特别是,我想知道fronzenset中的各个元素如何相互比较以及它们的总时间复杂度。
我看了set and frozenset difference in implementation和https://stackoverflow.com/a/51778365/5792721。
第二个链接中的答案涵盖了比较集合中各个元素之前的步骤,但缺少实际的比较算法。
答案 0 :(得分:4)
有关的实现可以在here中找到。假设我们要检查两个sets
v
和w
是否相等,算法就可以这样进行:
false
。 这引用了size
的{{1}}属性,因此它是恒定时间操作。
PySetObject
是否均为sets
。如果是这样,并且它们的哈希值不同,则返回frozensets
。同样,这引用了false
的{{1}}属性,这是一个恒定时间的操作。之所以可以这样做是因为hash
是不可变的对象,因此在创建它们时会计算其哈希值。
PySetObject
是否是frozensets
的子集。这是通过遍历w
的每个元素并检查其是否存在于v
中来完成的。
必须在所有v
上执行迭代,因此迭代的大小最差是线性的(如果在最后一个位置发现了不同的元素)。
w
的成员资格测试通常在平均情况下花费固定时间,而在最坏情况下花费线性时间;将两者结合起来,可以得到平均时间为v
的线性时间,最坏情况下的时间与sets
成比例。
从某种意义上讲,这是最坏情况的平均情况,因为它假定前两个检查总是返回v
。如果您的数据仅很少具有相等大小的len(v) * len(w)
,它们也具有相同的哈希值但包含不同的对象,那么在一般情况下,比较仍将在恒定时间内进行。
答案 1 :(得分:3)
set和frozenset都使用the set_richcompare()
function进行相等性测试。这里没有区别。
true
比较大小然后散列。然后,它checks whether one is a subset of the other仅循环遍历集合1中的每个元素,并检查它是否在集合2中。否则,该检查与checking whether an element is in a set相同。这是通过哈希表查找完成的,对具有相等哈希值的项目进行线性搜索。存在检查的复杂度为O(1) amortized or O(len(s)) worst-case,因此对sets
的检查的复杂度为O(len(s1))摊销,或者O(len(s1)* len(s2))最差-情况。