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

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

问题描述

我想了解如何落实乔恩斯基特在线程中的代码:
在C#中做一个范围查找



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



,其中,在第一组返回的1,2,3分别


$ b提取一个值$ b

我不太有怎么说也是在此代码做了把握。 。TX

 公共接口IRangeComparer< TRange,TValue> 
{
///<总结>
如果值是在指定范围内///返回0;
///小于0,如果值高于范围;
///大于0,如果值低于该范围。
///< /总结>
INT比较(TRange范围,TValue值);
}


///<总结>
///见Array.BinarySearch
///<合同; /总结>
公共静态INT二分查找< TRange,TValue>(IList的< TRange>范围,
TValue价值,
IRangeComparer< TRange,TValue>比较器)
{
INT分钟= 0;
INT最大= ranges.Count-1;

,而(分钟< =最大值)
{
INT中旬=(分+最大)/ 2;
INT比较= comparer.Compare(范围[MID],值);
如果(比较== 0)
{
返回中旬;
}
如果(比较℃,)
{
分钟=中期+ 1;
}
,否则如果(比较大于0)
{
最大=中等; 1
}
}
返回〜分钟;
}


解决方案

您需要有一个良好的仿制药的把握,理解这段代码。这里有一个功能的实现:

 公共类范围和LT; TValue> 
式TValue:IComparable的< TValue>
{
公共TValue敏{搞定;组; }
公共TValue最大{搞定;组; }

公开范围(TValue分,TValue最大)
{
this.Min =分钟;
this.Max =最大值;
}
}

公共类RangeComparer< TValue> :IRangeComparer<范围和LT; TValue>中TValue>
式TValue:IComparable的< TValue>
{
///<总结>
如果值是在指定范围内///返回0;
///小于0,如果值高于范围;
///大于0,如果值低于该范围。
///< /总结>
公众诠释比较(范围< TValue>的范围,TValue值)
{
//检查是否值低于范围(小于分钟)。
如果(range.Min.CompareTo(值)大于0)
返回1; //检查

如果值超过范围(大于max)
如果(range.Max.CompareTo(值)小于0)
返回-1;

//值在范围内。
返回0;
}
}

静态无效的主要(字串[] args)
{
变种范围=新的范围和LT; INT> []
{
新系列< INT>(1,10000),
新系列< INT>(10001,40000),
新系列< INT>(40001,int.MaxValue),
};

变种rangeComparer =新RangeComparer< INT>();

Console.WriteLine(二分查找(范围,7,rangeComparer)); //给0
Console.WriteLine(二分查找(范围,10007,rangeComparer)); //给1
Console.WriteLine(二分查找(范围,40007,rangeComparer)); //给2
Console.WriteLine(二分查找(范围,1,rangeComparer)); //给0
Console.WriteLine(二分查找(范围,10000,rangeComparer)); //给0
Console.WriteLine(二分查找(范围,40000,rangeComparer)); //给1
Console.WriteLine(二分查找(范围,40001,rangeComparer)); //给2
}



不要忘了:




  • 的范围必须按升序排列

  • 的范围不能重叠

  • 通过二分查找返回的索引是从零开始


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

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

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
}

Don’t forget that:

  • the ranges must be in ascending order
  • the ranges must not overlap
  • the indexes returned by BinarySearch are zero-based

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

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