【问题标题】:Fastest possible lookup for known static set of integers?对已知静态整数集的最快查找?
【发布时间】:2013-08-22 13:17:22
【问题描述】:

我正在实现一个 VM 编译器,当然,我已经到了实现开关的地步。同样自然地,对于短开关,顺序查找数组将是最佳的,但更大的开关呢?

到目前为止,我已经想出了一个数据结构,它可以让我有一个很好的查找时间。我不知道该结构的名称,但它类似于二叉树,但它是整体式的,不同之处在于它仅适用于一组静态整数,不能添加或删除。它看起来像一个表格,其中值从顶部和右侧递增,这是一个示例:

整数 -89、-82、-72、-68、-65、-48、-5、0、1、3、7、18、27、29、32、37、38、42、45、54 , 76, 78, 87, 89, 92

还有桌子:

-65    3   32   54   92
-68    1   29   45   89
-82   -5   18   38   78
-89   -48  7    37   76

这给了我最坏的情况width + height 迭代。假设情况是37,-65小于37,所以向右移动,3向右移动,32向右移动,54更大所以向下移动(步幅宽度,因为它是无论如何顺序数组),45 更大所以向下移动,38 更大所以向下移动,我们在 7 跳中有 37 个。

有没有更快的查找算法?

另外,这种安排有名称吗?我自己想出了它,但很可能是别人在我之前做的,所以它很可能已经命名了。

编辑:好的,据我所知,“完美哈希”将为我提供更好的理论性能。但这将如何在现实生活中发挥作用?如果我理解正确,两级“完美哈希”将被分散而不是连续的内存块,因此虽然理论上的复杂性较低,但在获取该内存之前可能会有数十个甚至数百个周期的潜在损失。相比之下,理论上较慢的最坏情况场景实际上会表现得更好,因为它比完美哈希更缓存友好......或者不是?

【问题讨论】:

  • 对排序列表进行二分搜索将在最多 5 次迭代中找到您的项目。 (在这个 20 项的列表中。)二分查找是 O(log n)。因此,从一百万个项目的列表中查找某些内容只需要 20 次迭代。
  • @JimMischel - 无论案件数量如何?我正在使用排序列表,但我需要宽度 + 高度迭代...
  • 为什么不存储遇到的整数并使用哈希表查找它们的索引?
  • 这只是一个菱形的二叉树。如果您想要更快的访问速度,我们可以使用平衡树或哈希表。如果在编译时所有数字都已知,您甚至可以构建一个完美的哈希。

标签: arrays algorithm performance switch-statement lookup


【解决方案1】:

在多种备选方案之间实施切换时,您有多种选择:

  • 制作几组平面查找数组。例如,如果您看到数字 1, 2, 3, 20000, 20001, 20002,您可以使用单个 if 将您带到 1-s 或 20,000-s,然后使用两个平面查找数组。
  • 发现一种模式。例如,如果您看到数字 100, 200, 300, 400, 500, 600,则将该数字除以 100,然后使用平面查找数组。
  • 制作一个哈希表。由于您知道要散列的所有数字,因此您可以使用表的负载因子来确保查找不会进行大量探测。

您的算法类似于二进制搜索,从某种意义上说,它来自“分而治之”系列。此类算法具有对数时间复杂度,对于交换机来说可能无法接受,因为它们预计为O(1)

【讨论】:

  • 由于width ~= height ~= sqrt(n),OP的算法是O(sqrt(n))。其他人建议使用二进制搜索,它会给你O(log2(n)),已经更好了。但是哈希表会给你O(1),所以这似乎确实是最好的方法。如果数字列表是固定且已知的,您应该能够找到一些不会给您带来冲突的哈希函数。
  • @BasSwinckels - 我不认为哈希表更快,需要运行一些测试。
  • 另一方面,如果条目的数量是固定的并且已知的(如果它不能改变!),那么可以计算实际成本,算法的大 O 是无关紧要的。散列通常是一个不错的选择,特别是如果你有一个便宜的散列算法。
  • @ddriver 哈希表不一定在所有情况下都更快,只是渐近更快。如果你有一个好的散列函数和一个好的负载因子,散列表几乎和平面数组查找一样快。相反,如果你的哈希函数很差,会产生大量冲突,你会得到更接近线性搜索的糟糕结果。
【解决方案2】:

有没有更快的查找算法?

二分查找更快。

二分查找在 log2(w*h) = log2(w) + log2(h) 中完成。

你的算法在 w+h 内完成。

【讨论】:

  • w+h 是最坏的情况
  • 是的,我已经计算了两种算法的最坏情况。
猜你喜欢
  • 1970-01-01
  • 2018-02-10
  • 2012-08-23
  • 1970-01-01
  • 1970-01-01
  • 2013-06-10
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多