algorithm - 二分查找小于或等于查找值的最接近值

标签 algorithm search binary-search

我正在尝试编写一种算法来查找小于或等于排序数组中搜索值的最接近值的索引。在数组[10, 20, 30] 的示例中,以下搜索值应输出这些索引:

  1. 搜索值:9,索引:-1
  2. 搜索值:10,索引:0
  3. 搜索值:28,索引:1
  4. 搜索值:55555,索引:2

我想对对数运行时间使用二进制搜索。我有一个 C 风格的伪代码算法,但它有 3 个基本情况。能否将这 3 个基本案例浓缩为 1 个以获得更优雅的解决方案?

int function indexOfClosestLesser(array, searchValue, startIndex, endIndex) {
  if (startIndex == endIndex) {
    if (searchValue >= array[startIndex]) {
      return startIndex;
    } else {
      return -1;
    }
  }

  // In the simplistic case of searching for 2 in [0, 2], the midIndex
  // is always 0 due to int truncation. These checks are to avoid recursing
  // infinitely from index 0 to index 1. 
  if (startIndex == endIndex - 1) {
    if (searchValue >= array[endIndex]) {
      return endIndex;
    } else if (searchValue >= array[startIndex]) {
      return startIndex;
    } else {
      return -1;
    }
  }

  // In normal binary search, this would be the only base case
  if (startIndex < endIndex) {
    return -1;
  }

  int midIndex = endIndex / 2 + startIndex / 2;
  int midValue = array[midIndex];

  if (midValue > searchValue) {
    return indexOfClosestLesser(array, searchValue, startIndex, midIndex - 1);
  } else if (searchValue >= midValue) {
    // Unlike normal binary search, we don't start on midIndex + 1.
    // We're not sure whether the midValue can be excluded yet
    return indexOfClosestLesser(array, searchValue, midIndex, endIndex);
  }
}

最佳答案

根据您的递归方法,我建议使用以下 c++ 片段来减少不同情况的数量:

int search(int *array, int start_idx, int end_idx, int search_val) {

   if( start_idx == end_idx )
      return array[start_idx] <= search_val ? start_idx : -1;

   int mid_idx = start_idx + (end_idx - start_idx) / 2;

   if( search_val < array[mid_idx] )
      return search( array, start_idx, mid_idx, search_val );

   int ret = search( array, mid_idx+1, end_idx, search_val );
   return ret == -1 ? mid_idx : ret;
}

基本上它执行正常的二进制搜索。只是最后一个case的return语句不同,满足了额外的要求。

这是一个简短的测试程序:

#include <iostream>

int main( int argc, char **argv ) {

   int array[3] = { 10, 20, 30 };

   std::cout << search( array, 0, 2, 9 ) << std::endl;
   std::cout << search( array, 0, 2, 10 ) << std::endl;
   std::cout << search( array, 0, 2, 28 ) << std::endl;
   std::cout << search( array, 0, 2, 55555 ) << std::endl;

   return 0;
}

输出如愿:

-1
 0
 1
 2

关于algorithm - 二分查找小于或等于查找值的最接近值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29196755/

相关文章:

algorithm - 如何证明有向无环图中至少存在一个入度为零的顶点?

c - 如何在 C 中实现带通滤波器(目的 : pitch detection)?

php - Laravel 在两个表中搜索 'LIKE' 查询

python - 如何通过python-3.6在网站html中搜索?

python - 通过字符串进行二分查找

python - 为什么在 python 中使用 Sublime 实现二进制搜索时无法在控制台上获得结果?

string - 有效地计算一个字符串和一大组其他字符串之间的编辑距离?

algorithm - 等于三元搜索树中的指针和限制

java - 如何在 O(n) 的排序数组中找到两个总和为给定数字的数字?

java - 二分查找算法包含一行我不明白的内容,有人可以帮我解释一下吗?