2009-05-29 75 views
8

作爲我正在構建的測試平臺的一部分,我正在尋找一個簡單的類來計算整數值的直方圖(用於解決問題的算法所需的迭代次數) 。答案應該被稱爲是這樣的:C#中整數數據的簡單直方圖生成

Histogram my_hist = new Histogram(); 

for(uint i = 0; i < NUMBER_OF_RESULTS; i++) 
{ 

    myHist.AddValue(some_result); 
} 

for(uint j = 0; j < myHist.NumOfBins; j++) 
{ 
    Console.WriteLine("{0} occurred {1} times", myHist.BinValues[j], myHist.BinCounts[j]); 
} 

我很驚訝了一下谷歌搜索不轉了一個整潔的解決方案,但也許我沒有尋找正確的事情。有沒有一個通用的解決方案,還是值得自己滾動?

回答

12

你可以使用SortedDictionary

uint[] items = new uint[] {5, 6, 1, 2, 3, 1, 5, 2}; // sample data 
SortedDictionary<uint, int> histogram = new SortedDictionary<uint, int>(); 
foreach (uint item in items) { 
    if (histogram.ContainsKey(item)) { 
     histogram[item]++; 
    } else { 
     histogram[item] = 1; 
    } 
} 
foreach (KeyValuePair<uint, int> pair in histogram) { 
    Console.WriteLine("{0} occurred {1} times", pair.Key, pair.Value); 
} 

這將離開了空箱,雖然

+0

+1:這看起來像一個好的開始。碰巧我只對包含數據的箱子感興趣:-) – 2009-05-29 14:31:00

6

基於BastardSaint的建議,我想出了一個整潔,相當通用的包裝:

public class Histogram<TVal> : SortedDictionary<TVal, uint> 
{ 
    public void IncrementCount(TVal binToIncrement) 
    { 
     if (ContainsKey(binToIncrement)) 
     { 
      this[binToIncrement]++; 
     } 
     else 
     { 
      Add(binToIncrement, 1); 
     } 
    } 
} 

所以現在我可以這樣做:

const uint numOfInputDataPoints = 5; 
Histogram<uint> hist = new Histogram<uint>(); 

// Fill the histogram with data 
for (uint i = 0; i < numOfInputDataPoints; i++) 
{ 
    // Grab a result from my algorithm 
    uint numOfIterationsForSolution = MyAlorithm.Run(); 

    // Add the number to the histogram 
    hist.IncrementCount(numOfIterationsForSolution); 
} 

// Report the results 
foreach (KeyValuePair<uint, uint> histEntry in hist.AsEnumerable()) 
{ 
    Console.WriteLine("{0} occurred {1} times", histEntry.Key, histEntry.Value); 
} 

花了我一段時間來弄清楚如何使它成爲通用的(首先,我只是覆蓋了SortedDictionary的構造函數,這意味着您只能使用它的uint鍵)。

+0

BastardSaint使用Contains()進行檢查的方法有點(很多)比依賴於異常更明智。這會在每次新數字的頻率被儲存時產生尖峯。 – 2009-05-29 15:35:17

3

可以使用的LINQ:

var items = new[] {5, 6, 1, 2, 3, 1, 5, 2}; 
items 
    .GroupBy(i => i) 
    .Select(g => new { 
     Item = g.Key, 
     Count = g.Count() 
    }) 
    .OrderBy(g => g.Item) 
    .ToList() 
    .ForEach(g => { 
     Console.WriteLine("{0} occurred {1} times", g.Item, g.Count); 
    }); 
0

此代碼給數組的值的圖形表示。

using System; 

// ... 
    static void Main(string[] args) 
    { 
     Console.ForegroundColor = ConsoleColor.Cyan; 
     int[] array = { 2, 2, 2 }; 
     PrintHistogram(array); 

     Console.ForegroundColor = ConsoleColor.Gray; 
     Console.Write("Press any key to quit . . . "); 
     Console.ReadKey(true); 
    } 

    static void PrintHistogram(int[] array) 
    { 
     int largest = 0; 

     for (int i = 0; i < array.Length; i++) 
      largest = Math.Max(largest, array[i]); 
     largest--; 

     // Bars 
     while (largest >= 0) 
     { 
      for (int i = 0; i < array.Length; i++) 
      { 
       if (array[i] > largest) 
        Console.Write("|\t"); 
       else 
        Console.Write("\t"); 
      } 

      largest--; 
      Console.WriteLine(); 
     } 

     Console.WriteLine(); 

     // Numbers 
     for (int i = 0; i < array.Length; i++) 
      Console.Write(array[i] + "\t"); 
     Console.WriteLine(); 
    }