【问题标题】:Array index of smallest number greater than a given number in a sorted array using C使用C的排序数组中大于给定数字的最小数字的数组索引
【发布时间】:2016-02-11 09:55:38
【问题描述】:

需要找到一个数字的索引,它可能存在也可能不存在于数组中。我尝试了以下代码:

#include <stdio.h>
#include <stdlib.h>

int cmp(const void *lhs, const void *rhs){
    return ( *(long long*)lhs - *(long long*)rhs );
}
int main(){
    int size = 9;
    long long a[] = {16426799,16850699,17802287,18007499,18690047,18870191,18870191,19142027,19783871};

    long long x = 17802287;
    long long *p  = (long long *)bsearch(&x, a, size, sizeof(long long), cmp);

    if (p != NULL)
        printf("%lld\n", p - a);
    return 0;
}

如果数字(在本例中为 17802287)存在于数组 a 中,则上述代码有效,但如果数字不存在于 a 中,则失败,例如没有为x=18802288 提供任何输出,我想获得索引i=5 在这种情况下第5 个元素开始的元素大于18802288。

另外,实际的数组大小将有超过 400 万个元素,相同的代码可以工作吗?

感谢您的帮助。

【问题讨论】:

  • 在标准 C 中没有这样的功能,但是用你想要的额外功能制作一个二分查找函数应该不会很难。创建自己的函数,您还可以添加一个参数,如果找到完全匹配则设置为非零,否则设置为零,以便调用者轻松决定如何处理结果。
  • 嗯,我试图将一些 python 代码移植到 C 中,卡在这里。我的 C 知识还不足以实现高效的搜索功能。
  • Binary search 是 (IMO) 最简单的搜索算法之一。尝试一下,尝试制作自己的二分搜索功能,只是一个返回完全匹配的简单功能(如bsearch),然后您可以对其进行调整以满足您的要求。但是请注意极端情况,如果您搜索的值大于数组中的最后一个元素,您的要求可能会给您带来麻烦。
  • 在 python 中找到了bisect_left 的源代码,因此将其移植到 C 中。效果很好。对我来说没有问题,因为数字会在数组的中间深处。

标签: c arrays binary-search-tree


【解决方案1】:

来自bsearch 的手册页:

bsearch() 函数返回一个指向匹配成员的指针 数组,如果未找到匹配项,则为 NULL。如果有多个 匹配键的元素,返回的元素是未指定的。

因此,如果未找到相关元素,该函数将返回 NULL。如果您想找到大于或等于相关数字的第一个元素,则需要滚动您自己的函数来做到这一点。

【讨论】:

    【解决方案2】:

    可能的解决方案之一是:

    int i, outcome = -1;
    for( i = 0; i < size; i++ )
    {
        if( x == a[i] )
        {
            outcome = i;
            break;
        }
    }
    
    printf("%d\n", outcome);
    

    【讨论】:

    • “实际数组大小也将有超过 400 万个元素” 这可能不是一个可行的解决方案。与原始解决方案一样,此代码仅在数组中存在x 时才有效..
    【解决方案3】:

    您需要编写一个大致完成此操作的函数:

    bsearch_geq (number array low high)
    
       if low is equal to high return high
    
       let halfway be average of low and high
    
       if array[halfway] is equal to number then return halfway
       if array[halfway] is greater than number then
          return result of "bsearch_geq number array low halfway"
       else
          return result of "bsearch_geq number array halfway high"
    

    我认为,这将帮助您完成 99% 的工作,但我将把它作为练习留给读者来找出极端情况。我能看到的主要问题是当你只剩下两个数字时会发生什么,因为天真的“平均”可能会导致无限递归。

    如果您可以在数组中多次出现 相同 数字,那么您需要删除 if array[halfway] is equal]" line

    您应该确保您的解决方案使用 tail-recursion 以提高效率,但这并不是太重要,因为 4m 数据条目仅相当于大约 15 次递归调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      • 2012-03-19
      • 2020-04-13
      • 1970-01-01
      相关资源
      最近更新 更多