Frage

Im Rahmen eines Prüfstandes Ich baue, ich bin auf der Suche nach einer einfachen Klasse ein Histogramm der Integer-Werte (Anzahl der Iterationen für einen Algorithmus genommen ein Problem zu lösen) zu berechnen. Die Antwort sollte wie folgt aufgerufen werden:

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

Ich war ein bisschen googeln überrascht hat keine saubere Lösung auftauchen, aber vielleicht habe ich nicht für die richtigen Dinge suchen. Gibt es eine generische Lösung gibt, oder ist es meine eigenen Wert rollen?

War es hilfreich?

Lösung

Sie könnten verwenden 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);
}

Dies wird leeren Behälter auslassen, obwohl

Andere Tipps

Basierend auf BastardSaint Vorschlag kam ich mit einem ordentlichen und ziemlich allgemein Wrapper:

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

So, jetzt kann ich tun:

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

dauerte eine Weile, um herauszufinden, wie es generische zu machen (beginnen ich overrode nur den SortedDictionary Konstruktor was bedeutete, dass man es nur für uint Schlüssel verwenden könnte).

Sie können Linq verwenden:

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);
    });
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top