查找范围内值的最佳方法
本文关键字:最佳 方法 范围内 查找 | 更新日期: 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);