[英]Checking against a changing set of integer ranges using C#
填写表格时,用户需要指定一个数量。 然后在大约4到6范围内检查此数量。 然后将所选范围保存在数据库中。 原始金额将不会存储(出于非技术原因) 。 范围之间将没有重叠,例如:
0-999
1000-1999
2000-4999
5000-9999
10000-higher
棘手的部分是这些范围不是一成不变的。 可以进行更改,也可以添加其他范围以进一步指定“ 10000及更高”范围。 这些更改将发生两次,并且无法避免。 由于无法将特定数量保存到数据库,因此需要存储旧范围。
对于一组变化的范围,最有效的C#数据结构是什么?
对于我的研究,我包括:
这里的一种简单方法是将较低频段的值存储在数组中,并将其传递给FindBand()
方法,该方法返回一个整数,该整数表示包含该值的频段的索引。
例如:
public static int FindBand(double value, double[] bandLowerValues)
{
for (int i = 0; i < bandLowerValues.Length; ++i)
if (value < bandLowerValues[i])
return Math.Max(0, i-1);
return bandLowerValues.Length;
}
测试代码:
double[] bandLowerValues = {0, 1, 2, 5, 10};
Console.WriteLine(FindBand(-1, bandLowerValues));
Console.WriteLine(FindBand(0, bandLowerValues));
Console.WriteLine(FindBand(0.5, bandLowerValues));
Console.WriteLine(FindBand(1, bandLowerValues));
Console.WriteLine(FindBand(1.5, bandLowerValues));
Console.WriteLine(FindBand(2.5, bandLowerValues));
Console.WriteLine(FindBand(5, bandLowerValues));
Console.WriteLine(FindBand(8, bandLowerValues));
Console.WriteLine(FindBand(9.9, bandLowerValues));
Console.WriteLine(FindBand(10, bandLowerValues));
Console.WriteLine(FindBand(11, bandLowerValues));
如果有很多频段,这不是最快的方法,但是如果只有几个频段,这可能足够快。
(如果有很多乐队,您可以使用二进制搜索来找到合适的乐队,但是在我看来,这太过分了。)
您可以对下限进行排序,例如
// or decimal instead of double if values are money
double[] lowBounds = new double[] {
0, // 0th group: (-Inf .. 0)
1000, // 1st group: [0 .. 1000)
2000, // 2nd group: [1000 .. 2000)
5000, // 3d group: [2000 .. 5000)
10000, // 4th group: [5000 .. 10000)
// 5th group: [10000 .. +Inf)
};
然后找到正确的组(从0开始 )
int index = Array.BinarySearch(lowBounds, value);
index = index < 0 ? index = -index - 1 : index + 1;
演示:
double[] tests = new double[] {
-10,
0,
45,
999,
1000,
1997,
5123,
10000,
20000,
};
var result = tests
.Select(value => {
int index = Array.BinarySearch(lowBounds, value);
index = index < 0 ? index = -index - 1 : index + 1;
return $"{value,6} : {index}";
});
Console.Write(string.Join(Environment.NewLine, result));
结果:
-10 : 0
0 : 1
45 : 1
999 : 1
1000 : 2
1997 : 2
5123 : 4
10000 : 5
20000 : 5
既然已经有关于如何找到正确范围的好答案,我想解决持久性问题。
我们有什么在这里?
因此,我可能要做的是在数据库中明确地保持上限和下限 。 这样,如果范围更改,则旧数据仍然正确。 您无法“转换”为新范围,因为您不知道它是否正确。 因此,您需要保留旧的值。 更改后的任何新条目将反映新范围。
可以想到标准化,但老实说,我认为这会使问题变得更加复杂。 我只会考虑如果好处(更少的存储空间)将大大超过复杂性问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.