【问题标题】:Using Array.BinarySearch() to return first value <= lookup value?使用 Array.BinarySearch() 返回第一个值 <= 查找值?
【发布时间】:2010-08-11 05:03:50
【问题描述】:

我正在尝试创建一个“查找”列,该列将返回等于或小于正在查找的值的数组值的索引。所以这是我的尝试,似乎效果很好,但我想知道是否有更清洁的方法?

// Sorted
float[] ranges = new float[]
  {
     0.8f,
     1.1f,
     2.7f,
     3.9f,
     4.5f,
     5.1f,
  };


private int GetIndex(float lookupValue)
{
    int position = Array.BinarySearch(ranges, lookupValue);
    if (position < 0)
    {
        // Find the highest available value that does not
        // exceed the value being looked up.
        position = ~position - 1;
    }

    // If position is still negative => all values in array 
    // are greater than lookupValue, return 0
    return position < 0 ? 0 : position;
}

谢谢。

【问题讨论】:

  • BinarySearch 很快,我认为你所拥有的非常干净。
  • 定义 'cleaner' 代码有效。它很简洁。评论不错。你还在寻找什么?
  • 虽然上面的解决方案假设输入数组是排序的......
  • 从我的偏好中清除意味着删除冗长的 cmets,但这是一种偏好。我不会碰代码..我认为你有最好的解决方案。
  • 也许使用 Array.BinarySearch Method (Array, Object, IComparer) 代替?

标签: c# arrays lookup where-clause binary-search


【解决方案1】:

不,我认为这是一个很好的方法。

我唯一可能改变的是使其成为数组的扩展方法,而不是引用类变量的私有函数。然后它变得通用/不依赖于一个类,语法也更清晰:ranges.GetIndex(...)

类似这样的:

public static class Extensions
{
    public static int GetIndex<T>(this T[] ranges, T lookupValue)
    {
        // your code here
    }
}

当然,您必须记住,这只适用于已排序的数组...

【讨论】:

  • +1 因为扩展很好,虽然我可能会限制类型,所以你没有智能感知在一些复杂数据类型的数组上弹出这个 GetIndex..
【解决方案2】:

您可以使用普通的 for 循环(假设您的数据是有序的)。不确定它是否更干净,但在大量数据上肯定没有那么有效。我个人会选择您拥有的 BinarySearch。

int GetIndex(IList<float> ranges, float target)
{
    for (int i = 0; i < ranges.Count; i++)
    {
        if(ranges[i] < target) continue;
        if (ranges[i] >= target) return i;
    }
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 2019-05-14
    • 1970-01-01
    • 2019-03-22
    • 2017-09-02
    相关资源
    最近更新 更多