【发布时间】:2011-06-09 12:21:26
【问题描述】:
我想预先计算一些一元函数f的值数组。
我知道我只需要f(x) 的值,其中x 的形式为a*b,其中a 和b 都是0..N 范围内的整数。
明显的时间优化选择只是创建一个大小为N*N 的数组,并且只预先计算我稍后将要阅读的元素。对于f(a*b),我只需检查并设置tab[a*b]。这是可能的最快方法 - 但是,这将占用大量空间,因为该数组中有很多索引(以 N+1 开头)永远不会被触及。
另一种解决方案是制作一个简单的树形图......但这会通过引入大量分支而大大减慢查找本身的速度非常。没有。
我想知道 - 是否有任何解决方案可以使这样的数组不那么稀疏和更小,但在查找中仍然快速无分支 O(1)?
编辑
我可以听到很多关于哈希映射的 cmets... 我将继续对一个行为的行为进行基准测试 (我预计由于分支,性能会比正常查找显着下降;低于树,但仍然如此。 ..让我们看看我是否正确!).
我想强调:我最喜欢分析解决方案,它会使用一些聪明的方法 (?) 来利用仅采用“类产品”索引这一事实.我觉得这个事实可能会被利用来获得比普通的通用哈希映射函数更好的结果,但我自己没有想法。
编辑
按照您的建议,我从 gcc 4.5 尝试了 std::unordered_map。这比简单的数组查找慢了一点,但确实比基于树的std::map 快得多 - 最终我对这个解决方案感到满意。我现在明白了为什么不能做我最初打算做的事情;感谢您的解释!
我只是不确定哈希映射是否真的节省了任何内存! :) 正如@Keith Randall 所描述的,我无法使内存占用低于N*N/4 和三角矩阵@Sjoerd 描述的方法给了我N*N/2。我认为,如果元素大小很小(取决于容器开销),哈希映射完全有可能使用超过 N*N/2 空间 - 这将使最快的方法也是最有效的内存!我会试着检查一下。
我希望我能接受 2 个答案...
【问题讨论】:
-
你能把
f改成f(a, b)吗? -
当然......即使是包装器也可以做到这一点。结果仅取决于产品。
-
嗯,不清楚您在通话时是否真的知道
a和b,或者您是否只知道x。 -
如果您找到一种快速跳过未使用条目的方法,它可以变成一种快速判断数字是否为素数的方法。由于后者被认为是一个难题,我怀疑你会为你的问题找到一个好的分析解决方案。
标签: c++ algorithm sparse-array