在 C# 中进行范围查找 - 如何实现 [英] Doing a range lookup in C# - how to implement

查看:28
本文介绍了在 C# 中进行范围查找 - 如何实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解如何实现 Jon Skeet 在线程中找到的代码:在 C# 中进行范围查找?

I'm trying to understand how to implement the code found in thread by Jon Skeet: Doing a range lookup in C#?

有人可以提供使用以下内容的设置示例:1-10000, 10001-40000, 40000+

Can someone provide an setup example using something like: 1-10000, 10001-40000, 40000+

第一组在哪里分别返回1、2、3的值?

where is the first group returns a value of 1, 2, 3 respectively?

我不太了解这段代码是如何完成的.发送.

I don't quite have a grasp of how that is done in this code. tx.

public interface IRangeComparer<TRange, TValue>
{
    /// <summary>
    /// Returns 0 if value is in the specified range;
    /// less than 0 if value is above the range;
    /// greater than 0 if value is below the range.
    /// </summary>
    int Compare(TRange range, TValue value);
}


/// <summary>
/// See contract for Array.BinarySearch
/// </summary>
public static int BinarySearch<TRange, TValue>(IList<TRange> ranges,
                                               TValue value,
                                               IRangeComparer<TRange, TValue> comparer)
{
    int min = 0;
    int max = ranges.Count-1;

    while (min <= max)
    {
        int mid = (min + max) / 2;
        int comparison = comparer.Compare(ranges[mid], value);
        if (comparison == 0)
        {
            return mid;
        }
        if (comparison < 0)
        {
            min = mid+1;
        }
        else if (comparison > 0)
        {
            max = mid-1;
        }
    }
    return ~min;
}

推荐答案

你需要很好地掌握泛型才能理解这段代码.这是一个函数式实现:

You need to have a good grasp of generics to understand this code. Here’s a functional implementation:

public class Range<TValue> 
    where TValue : IComparable<TValue>
{
    public TValue Min { get; set; }
    public TValue Max { get; set; }

    public Range(TValue min, TValue max)
    {
        this.Min = min;
        this.Max = max;
    }
}

public class RangeComparer<TValue> : IRangeComparer<Range<TValue>, TValue> 
    where TValue : IComparable<TValue>
{
    /// <summary>
    /// Returns 0 if value is in the specified range;
    /// less than 0 if value is above the range;
    /// greater than 0 if value is below the range.
    /// </summary>
    public int Compare(Range<TValue> range, TValue value)
    {
        // Check if value is below range (less than min).
        if (range.Min.CompareTo(value) > 0)
            return 1;

        // Check if value is above range (greater than max)
        if (range.Max.CompareTo(value) < 0)
            return -1;

        // Value is within range.
        return 0;
    }
}

static void Main(string[] args)
{
    var ranges = new Range<int>[]
    {
        new Range<int>(1, 10000),
        new Range<int>(10001, 40000),
        new Range<int>(40001, int.MaxValue),
    };

    var rangeComparer = new RangeComparer<int>();

    Console.WriteLine(BinarySearch(ranges, 7, rangeComparer));       // gives 0
    Console.WriteLine(BinarySearch(ranges, 10007, rangeComparer));   // gives 1
    Console.WriteLine(BinarySearch(ranges, 40007, rangeComparer));   // gives 2
    Console.WriteLine(BinarySearch(ranges, 1, rangeComparer));       // gives 0
    Console.WriteLine(BinarySearch(ranges, 10000, rangeComparer));   // gives 0
    Console.WriteLine(BinarySearch(ranges, 40000, rangeComparer));   // gives 1
    Console.WriteLine(BinarySearch(ranges, 40001, rangeComparer));   // gives 2
}

别忘了:

  • 范围必须按升序排列
  • 范围不得重叠
  • BinarySearch 返回的索引是从零开始的
  • the ranges must be in ascending order
  • the ranges must not overlap
  • the indexes returned by BinarySearch are zero-based

这篇关于在 C# 中进行范围查找 - 如何实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆