查找范围内值的最佳方法

本文关键字:最佳 方法 范围内 查找 | 更新日期: 2023-09-27 18:22:28

我有一组值:

  • [0-20]=1
  • [21-30]=2
  • [31-40]=3等

例如,我期望用户在[44]的for中输入。确定价值落在哪个项目上最有说服力的方法是什么?

我可以写一个switch语句来匹配案例><或者一个if…的陈述,但在我看来,这两个都不够雄辩。

更新

我正在寻找一种整洁的方法来查找用户输入的范围,例如使用LAMDBA:

List<int>().Find(x => x.WithinRange(range))

或者类似的东西。

查找范围内值的最佳方法

如果您的范围是连续的,就像您的例子中一样(即没有间隙),您可以将它们的端点存储在一个数组中,如下所示:

var endpoints = new[] {20, 30, 40, 60, 90};

请注意,端点已排序。现在,您可以使用二进制搜索方法来查找将返回的数组中44的插入点,即3(二进制搜索将返回3的逐位补码;您需要应用~才能获得实际值)。

好了:

int GetRange(int value) 
{ 
    return (value > 30) ? 3 :
           (value > 20) ? 2 :
           (value > 0)  ? 1 :
           0;
}

没有如果!

像这样的扩展:

public static int WithinRange(this int value)
{
    if (value < 0) return 0;
    if (value < 21) return 1;
    return (value - 1) / 10;
}

if语句

public static int WithinRange(this int value)
{
    return (value < 0) ? 0 
        : (value < 21) ? 1 
        : (value - 1) / 10;
}

用法:

collection.Find(x => x.WithinRange(range)) 

只需在范围内循环,看看值是否在范围内。。。

var ranges = new[]
{
    Tuple.Create(0, 20),
    Tuple.Create(21, 30),
    Tuple.Create(31, 40),
    Tuple.Create(41, 50),
    // ...
};
var number = 44;
for (int i = 0; i < ranges.Length; i++)
{
    var range = ranges[i];
    if (number >= range.Item1 && number <= range.Item2)
    {
        var theIndex = i + 1;
        // do something with theIndex
    }
}

您可以直接操作输入:

int input = //Whatever the input is
int index = (input-1)/10;

假设输入整数,并且您的数组已按指示进行索引。

@Jeff Mercado答案的效率较低的.NET 3.5替代变体:

var ranges = new[]
{
    Enumerable.Range(0, 20),
    Enumerable.Range(21, 30),
    Enumerable.Range(31, 40),
    Enumerable.Range(41, 50),
    // ...
};
var number = 44;
for (int i = 0; i < ranges.Length; i++)
{
    var range = ranges[i];
    if (range.Contains(number))
    {
        var theIndex = i + 1;
        // do something with theIndex
    }
}

UPDATE:我知道这是一种过度的做法,但它可能会给你一些想法。正如我所说,你已经知道如何解决这个问题,但你只是在寻找一个"更漂亮"的解决方案:

public class Range
{
    public int Left { get; set; }   
    public int Right { get; set; }
    public string Title { get; set; }
    public Range(int left, int right, string title) { Left = left; Right = right; Title = title; }
    public bool Contains(int x) { return Left <= x && x <= Right; }
}
void Main()
{
    var x = 15;
    var ranges = new[] {
        new Range(0, 10, "A"),
        new Range(11, 20, "B")
    };
    var foo = ranges.Where(r => r.Contains(x)).Single();
    Console.Write(foo.Title);
}

我之前的建议For语句可以,但我更喜欢LINQ:)

var x = 15;
var ranges = new[] { Tuple.Create(0, 10), Tuple.Create(11, 20) };
var range = ranges.Where(r => r.Item1 <= x && r.Item2 >= x );
Console.Write(range.Item1);
Console.Write(range.Item2);