【发布时间】:2013-09-26 15:39:38
【问题描述】:
我想将我已经编写的一些 Python 代码翻译成 C++ 或其他快速语言,因为 Python 的速度不够快,无法完成我想做的事情。然而,有问题的代码滥用了 Python 集合的一些令人印象深刻的特性,特别是我在性能关键循环中发送垃圾邮件的平均 O(1) 成员资格测试,而且我不确定如何用另一种语言实现 Python 集合。
在Python's Time Complexity Wiki Page 中,它指出集合的成员资格测试平均为 O(1),最坏情况下为 O(n)。我使用timeit 亲自对此进行了测试,并且惊讶于 Python 集执行成员资格测试的速度之快,即使 N 很大。我查看了this Stack Overflow answer 以了解 C++ 集在使用 find 操作以查看元素是否为给定集合的成员,它说它是 O(log(n))。
我假设 find 的时间复杂度是对数的,因为 C++ 标准库集是用某种二叉树实现的。我认为因为 Python 集具有平均 O(1) 成员资格测试和最坏情况 O(n),它们可能是用某种带有桶的关联数组实现的,它可以轻松查找一个元素并对其进行一些虚拟值测试这表明该元素不是集合的一部分。
问题是,我不想通过切换到另一种语言来减慢代码的任何部分(因为这是我试图首先解决的问题)所以我如何实现我自己的 Python 版本用另一种语言设置(特别是快速会员测试)?有人知道 Python 集是如何实现的吗?如果不知道,谁能给我任何一般性的提示来指出正确的方向?
我不是在寻找源代码,我只是在寻找可以帮助我入门的一般想法和链接。
我对@987654323@ 进行了一些研究,我想我了解它们实现背后的基本思想,但我不确定它们的内存使用情况。如果 Python 集确实只是真正的关联数组,我怎样才能以最少的内存使用来实现它们?
附加说明:我要使用的相关集合最多包含 50,000 个元素,并且集合中的每个元素都在一个很大的范围内(例如 [-999999999, 999999999])。
【问题讨论】:
-
如果您想在 C++ 中进行 O(1) 查找,请使用
std::unordered_set。但是,50k 个元素并不多,在标准std::set中进行查找应该需要少于 16 次比较。 -
我绝对想要 O(1) 查找,因为我在一个循环中有多个查找。感谢 unordered_sets 的链接,我不知道 std 库有这个。这可能会为我省去很多麻烦。
标签: c++ python c arrays algorithm