2

对于一个项目,我需要实现二进制搜索。这种二分搜索允许重复。我必须获取与我的目标匹配的所有索引值。如果发现中间有重复,我考虑过这样做:

Target = G 假设有以下排序数组:

B、D、E、F、G、G、G、G、G、G、Q、RS、S、Z

我得到的是 7 的中间值。由于双方都有目标匹配,并且我需要所有目标匹配,我认为获取所有目标的一个好方法是检查 mid + 1 是否是相同的值。如果是,请继续向右移动,直到不是。所以,结果会是这样的:

B、D、E、F、G、G、G、G、G、G(中)、Q、RS、S、Z

然后我会从 0 到 mid 来计算目标匹配并将它们的索引存储到一个数组中并返回它。

如果中间是匹配的并且重复恰好在第一次在中间并且在阵列的两侧,这就是我正在考虑的方式。


现在,如果第一次不匹配怎么办?例如:

B、D、E、F、G、G、J、K、L、O、Q、R、S、S、Z

然后像往常一样,它会抓取中间,然后从 first 到 mid-1 调用二进制搜索。

B、D、E、F、G、G、J

由于 G 大于 F,调用从 mid+1 到 last 的二分查找。

G,G,J。

中场是一场比赛。既然是匹配,就从 mid+1 到 last 通过 for 循环搜索,并计算匹配的数量,并将匹配索引存储到数组中并返回。

这是二进制搜索获取所有重复项的好方法吗?如果您在我的算法中发现问题以及提示/建议(如果有),请告诉我。我看到的唯一问题是,如果所有匹配项都是我的目标,我基本上会搜索整个数组,但是如果是这样的话,我仍然需要获取所有重复项。

谢谢

顺便说一句,我的导师说我们不能使用向量、哈希或其他任何东西。他希望我们保持在阵列级别,并习惯于使用和操作它们。

4

4 回答 4

2

为什么一找到匹配项就想摆脱使二分搜索如此出色的原因?为什么不在上半部分使用二分搜索并缩小范围,直到不再得到 G,然后对下半部分执行相同操作。这样,在最坏的情况下,您不会搜索整个数组。您以这种方式找到最小和最大索引,然后将它们加上所有中间索引存储在一个数组中。

于 2010-03-13T05:49:34.427 回答
2

参考stl中lower_bound函数的源码。

如果您手头或学校图书馆中有一本 Programming Pearls,请参阅本书末尾的第 4 章及其解决方案。

于 2010-03-13T06:41:11.430 回答
2

我用一个对数组使用修改后的二进制搜索算法的解决方案回答了这个问题。由于这是家庭作业,除非您希望它被破坏,否则不要单击链接,但要点是通过修改二进制搜索循环中的条件,您可以让它执行以下 3 种行为中的任何一种:

  1. 在找到匹配项时返回匹配项(正常行为,匹配项可以是一系列相同值的任何位置)
  2. 返回最左边的匹配
  3. 返回最右边的匹配

然后通过运行此二进制搜索两次来回答您的问题,一次找到最左边的匹配,然后再次找到最右边的匹配(仅当第一次运行成功时)。两个结果之间的差异,即匹配索引,比找到的总匹配数少 1。

于 2010-03-14T12:02:10.387 回答
0

请注意,您不是在搜索元素 X,而是在搜索边界 Y,X,其中 Y < X,对称地搜索 X,Z,其中 X < Z。这些边界也可以通过虚构的二分搜索找到由元素间边界组成的数组。

于 2010-03-13T07:05:28.027 回答