在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] ); } 

我很惊讶有点谷歌搜索没有找到一个简洁的解决方案,但也许我没有找到正确的事情。 那里有一个通用的解决方案还是值得我自己推出?

你可以使用SortedDictionary

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

但这会留下空箱子

根据BastardSaint的建议,我提出了一个整洁且相当通用的包装器:

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

所以我现在能做到:

 const uint numOfInputDataPoints = 5; Histogram hist = new Histogram(); // 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 histEntry in hist.AsEnumerable()) { Console.WriteLine("{0} occurred {1} times", histEntry.Key, histEntry.Value); } 

我花了一些时间来研究如何使它成为通用的(首先我只是覆盖了SortedDictionary构造函数,这意味着你只能将它用于uint键)。

你可以使用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); }); 

此代码提供了数组值的图形表示。

 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(); }