填写表格时,用户需要指定一个金额。然后在大约4到6范围内检查此数量。然后将所选范围保存在数据库中。 原始金额将不会存储(出于非技术原因)。范围之间没有重叠,例如:
0-999
1000-1999
2000-4999
5000-9999
10000-higher
棘手的部分是这些范围不是一成不变的。可以进行更改,也可以添加其他范围以进一步指定“ 10000及更高”范围。这些更改将发生两次,并且无法避免。由于无法将特定范围保存到数据库,因此需要存储旧范围。
用于检查一组不断变化的范围的最有效的C#数据结构是什么?
我的研究包括:
One of the answers here建议使用C#7在switch语句中可以使用一组固定的整数范围。但是,不可能向switch语句动态添加案例和/或从switch语句删除案例。
This question建议使用Enumerable.Range并不是最有效的方法。
答案 0 :(得分:1)
这里的一种简单方法是将较低频段的值存储在数组中,并将其传递给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));
如果有很多频段,这不是最快的方法,但是如果只有几个频段,这可能足够快。
(如果有很多乐队,您可以使用二进制搜索来找到合适的乐队,但我认为这样做会过分杀伤了。)
答案 1 :(得分:1)
您可以对下界进行排序,例如
// 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
答案 2 :(得分:0)
由于有关如何找到正确范围的答案已经很多,因此我想解决持久性问题。
我们在这里有什么?
因此,我可能要做的是在数据库中明确地将上限和下限持久化。 这样,如果范围更改,则旧数据仍然正确。您无法“转换”为新范围,因为您不知道它是否正确。因此,您需要保留旧的值。更改后的任何新条目都将反映新范围。
人们可以想到标准化,但是老实说,我认为这会使问题变得更加复杂。我只会考虑如果好处(更少的存储空间)将大大超过复杂性问题。