【问题标题】:Inexact Binary Search: Given a Value, Find the Upper and Lower Index Of The Element Position不精确二分搜索:给定一个值,找到元素位置的上下索引
【发布时间】:2010-07-13 12:18:40
【问题描述】:

我有一个List<KeyValuePair<double, double>>列表按KeyValuePair.Key排序,因此可以修改为二进制搜索。我有一个double 对象。现在,我的任务是找到double 对象的索引。以下是适用的条件:

  1. 如果该double 对象在指定的容差范围内匹配KeyValuePair.Key 之一,则应返回相应的KeyValuePair.Value
  2. 如果double 对象超出KeyValuePair.Key 的最大和最小范围,则应返回0。
  3. 如果double 对象在KeyValuePair.Key 的最大最小值范围内,但在指定容差范围内与KeyValuePair.Key 中的任何一个都不匹配,则获取最接近的上限和最接近的下限KeyValuePair.Value 的平均值(由KeyValuePair.Key 测量)。

我知道 C# 中提供了二进制搜索实现,但它并不完全适合我的需要。我想问一下是否有任何实现已经满足我的需求?我不想花几个小时编写和调试其他人已经编写、调试和完善的代码。

【问题讨论】:

    标签: c# binary-search


    【解决方案1】:

    这可以通过一个比较器和一个围绕List<T>.BinarySearch 的小包装器相当容易地完成:

    static double Search(List<KeyValuePair<double, double>> list, double key) {
        int index = list.BinarySearch(
            new KeyValuePair<double, double>(key, 0), 
            new Comparer());
    
         // Case 1
         if (index >= 0)
             return list[index].Value;
    
         // NOTE: if the search fails, List<T>.BinarySearch returns the 
         // bitwise complement of the insertion index that would be used
         // to keep the list sorted.
         index = ~index;
    
         // Case 2
         if (index == 0 || index == list.Count)
            return 0;
    
         // Case 3
         return (list[index - 1].Value + list[index].Value) / 2;
     }
    
     class Comparer : IComparer<KeyValuePair<double, double>> {
         public int Compare(
             KeyValuePair<double, double> x, 
             KeyValuePair<double, double> y) 
         {
             if (Math.abs(x.Key - y.Key) < TOLERANCE)
                 return 0;
    
             return x.Key.CompareTo(y.Key);
         }
     }
    

    【讨论】:

    • 您可能需要注意的唯一一件事是 id 列表包含重复项:如果 List 包含多个具有相同值的元素,则该方法仅返回其中一个,并且它可能会返回任何一个事件,不一定是第一个。
    • 不错...我没有意识到BinarySearch实际上返回了插入索引的按位补码...谢谢!
    • @Mitch,对于我的应用程序,所有Keys 都是唯一的,所以不用担心。
    • @Mitch 好点!另外,感谢您指出我忘记处理原始解决方案中的公差要求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-19
    • 2021-05-10
    • 2014-04-19
    • 2013-12-27
    • 2011-11-11
    • 2021-08-17
    • 1970-01-01
    相关资源
    最近更新 更多