【问题标题】:Fast way to count smaller/equal/larger elements in array快速计算数组中较小/相等/较大元素的方法
【发布时间】:2018-06-26 15:13:02
【问题描述】:

我需要优化我的算法,以计算数组(未排序)中比给定数字更大/更小/相等的数字。

我必须这样做很多次,给定的数组也可以有数千个元素。

数组不变,数字在变

例子:

数组:1,2,3,4,5

n = 3

  • 的数量
  • >的数量:2
  • ==:1 的数量

第一个想法:

遍历数组并检查元素是否>或O(n*k)

可能的优化:

O((n+k) * logn)

首先对数组进行排序(我使用c qsort),然后使用二进制搜索找到相等的数字,然后以某种方式计算越来越小的值。但是该怎么做呢?

如果元素存在(bsearch 返回指向该元素的指针)我还需要检查数组是否包含此元素的可能重复项(因此我需要检查此元素之前和之后,而它们等于找到的元素),然后使用一些指针操作来计算更大和更小的值。 如何获得具有指向相等元素的指针的更大/更小的值的数量? 但是如果我没有找到值怎么办(bsearch返回null)?

【问题讨论】:

  • 如果你只需要一个/几个n,那么你的“优化”实际上就是“去优化”。
  • 排序,运气好,算法是 O(n logn),之后你做什么都会让情况变得更糟。扫描一次数组,增加三个计数器,将是 O(n)。您想要实现的优化在哪里?
  • 但在最好的情况下(没有重复)我认为我节省了很多时间
  • 认为?那就证明吧。这些东西有一个完善的科学记数法。
  • 所以..您实际上已经接受了答案并将其编辑到问题中,使所说的一切无效....并且几乎消除了问题本身的意义。现在还不清楚你在问什么。

标签: c arrays algorithm optimization binary-search


【解决方案1】:

如果数组是未排序的,并且其中的数字没有其他有用的属性,则无法击败遍历数组一次并计算三个桶中的项目的 O(n) 方法。

假设您使用时间线性的排序算法(例如基数排序),对数组进行排序然后进行二进制搜索不会比 O(n) 更好。对于基于比较的排序,例如快速排序,时间会增加到 O(n*log2n)。

另一方面,如果您需要针对同一组数字运行多个查询,排序会有所帮助。假设线性时间排序,对 n 个数字进行 k 次查询的时间将从 k 线性搜索的 O(n*k) 变为 O(n+k*log2n),或 O((n+k)*log2n) 与基于比较的排序。给定足够大的 k,平均查询时间会下降。

【讨论】:

  • @klm 这是您遗漏的一个重要细节。请更新您的问题,描述您真正想要做什么。
  • 所以这将取决于相对于数组大小的次数。
  • 为什么是O(n + k log n)
  • @0x499602D2 n log n 用于排序,k log n 用于k 二进制搜索。
  • @EugeneSh。那不是O((n+k)log n)吗?
【解决方案2】:
  1. 由于数组(显然?)没有改变,因此对其进行预排序。这允许二进制搜索 (Log(n))

    a.) 实现您自己的 bsearch 版本(无论如何代码会更少)

    • 您可以使用索引与指针进行内联操作
    • 您不需要指向专用函数的函数指针

    b.) 由于您说要计算匹配数,因此您暗示该数组可以包含具有相同值的多个条目(否则您将使用布尔值 h​​as_n)。

    • 这意味着您需要对“n”s 数组的开头和结尾进行线性搜索。
    • 从中可以计算出小于 n 和大于 n 的数。
    • 您似乎有一些不成文的算法来选择这些(对于 n=3,您会查找大于和小于 2 且等于 1 的值的计数,因此无法给出具体代码)

    c.) 为了进一步优化(以内存为代价),您可以将数据排序到结构的二叉搜索树中,该树不仅包含值,还包含每个值之前和之后的值的计数和数量。如果你有很多重复值,它可能根本不会使用更多的内存,但是如果没有数据集就很难判断。

  2. 如果没有描述隐藏算法和数据的代码,或者至少没有足够的描述(除了推荐数据结构和算法方面的一门或多门课程),我能提供的帮助就这么多。

【讨论】:

  • 谢谢,现在我需要了解如何重写返回索引但不检查相等性的二进制搜索。所以“寻找n,如果存在则返回索引,如果不存在则返回应该在的索引”并在调用此检查相等之后
猜你喜欢
  • 2019-06-05
  • 1970-01-01
  • 2015-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多