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