簡體   English   中英

使用C#檢查一組變化的整數范圍

[英]Checking against a changing set of integer ranges using C#

填寫表格時,用戶需要指定一個數量。 然后在大約4到6范圍內檢查此數量。 然后將所選范圍保存在數據庫中。 原始金額將不會存儲(出於非技術原因) 范圍之間將沒有重疊,例如:

  • 0-999
  • 1000-1999
  • 2000-4999
  • 5000-9999
  • 10000-higher

棘手的部分是這些范圍不是一成不變的。 可以進行更改,也可以添加其他范圍以進一步指定“ 10000及更高”范圍。 這些更改將發生兩次,並且無法避免。 由於無法將特定數量保存到數據庫,因此需要存儲舊范圍。

對於一組變化的范圍,最有效的C#數據結構是什么?

對於我的研究,我包括:

  • 此處的答案之一表明,使用C#7,可以在switch語句中使用一組固定的整數范圍。 但是,不可能向switch語句動態添加案例和/或從switch語句刪除案例。

  • 這個問題表明使用Enumerable.Range不是最有效的方法。

這里的一種簡單方法是將較低頻段的值存儲在數組中,並將其傳遞給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

既然已經有關於如何找到正確范圍的好答案,我想解決持久性問題。

我們有什么在這里?

  1. 您不能保留確切的值。 ( 不允許 )
  2. 值將通過使它們適合范圍而被“模糊”。
  3. 這些范圍可以(並且將)隨着時間的推移在范圍和數量上變化。

因此,我可能要做的是在數據庫中明確地保持上限和下限 這樣,如果范圍更改,則舊數據仍然正確。 您無法“轉換”為新范圍,因為您不知道它是否正確。 因此,您需要保留舊的值。 更改后的任何新條目將反映新范圍。

可以想到標准化,但老實說,我認為這會使問題變得更加復雜。 我只會考慮如果好處(更少的存儲空間)將大大超過復雜性問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM