鉴于下面显示的'原始代码'(来自主题Doing a range Lookup)
我正在尝试实现一个将包装BinarySearch例程的TableLookUp方法。我更改了Range类以接受value属性。我创建了TableLookUp例程,但我知道这是错误的。我不知道如何调用BinarySearch方法来实现这一点。仿制药让我感到困惑。
提前Tx!
调用的值可能如下:
var ranges = new Range<int>[]
{
new Range<int>(1, 10000, 22),
new Range<int>(10001, 40000, 33),
new Range<int>(40001, int.MaxValue, 44)
};
使用以下代码替换Range类:
public class Range<TValue>
where TValue : IComparable<TValue>
{
public TValue Min { get; set; }
public TValue Max { get; set; }
public int Value { get; set; }
public Range(TValue min, TValue max, int value)
{
this.Min = min;
this.Max = max;
this.Value = value;
}
}
将包装器添加到二进制搜索:
public static int LookUpTable<TRange, TValue>(IList<TRange> ranges, TValue value, IRangeComparer<TRange, TValue> comparer)
{
int indexToTable = BinarySearch(ranges, value, comparer);
Range<TRange> lookUp = ranges[indexToTable];
return lookUp.Value;
}
将main中的调用代码替换为以下内容:
Console.WriteLine(LookUpTable(ranges, 7, rangeComparer));
Console.WriteLine(LookUpTable(ranges, 10007, rangeComparer));
Console.WriteLine(LookUpTable(ranges, 40007, rangeComparer));
Console.WriteLine(LookUpTable(ranges, 1, rangeComparer));
原始代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestConsole
{
class Program
{
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;
}
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
Console.WriteLine("Press any key to continue...");
Console.ReadKey(true);
}
}
}
答案 0 :(得分:1)
public static int LookUpTable<TRange, TValue>(IList<TRange> ranges, TValue value, IRangeComparer<TRange, TValue> comparer)
where TRange : Range<TValue> // Specify what you know about TRange and TValue
where TValue : IComparable<TValue>
{
int indexToTable = BinarySearch(ranges, value, comparer);
TRange lookUp = ranges[indexToTable]; // lookUp is TRange, not Range<TRange>
return lookUp.Value;
}