| 

.NET C# Java Javascript Exception

4
In letzter Zeit stelle ich mir immer wieder die Frage, ob man bestimmte Funktionen nicht effizienter schreiben kann, hinsichtlich Laufzeit und Speicherverbrauch.

Zur Zeit sitze ich an einer einfachen Funktion, die das Minimum von vier Zahlen ausgeben soll. Es dürfen nicht mehr und nicht weniger Zahlen sein, sondern nur vier.
Aktuell sieht meine Funktion so aus:
/// <summary>
/// Returns the minimum of four numbers.
/// </summary>
/// <param name="a">First number.</param>
/// <param name="b">Second number.</param>
/// <param name="c">Third number.</param>
/// <param name="d">Fourth number.</param>
/// <returns>Minimum of a, b, c and d.</returns>
private int Min(int a, int b, int c, int d)
{
int[] numbers = new int[4];
numbers[0] = a;
numbers[1] = b;
numbers[2] = c;
numbers[3] = d;

Array.Sort(numbers);
return numbers[0];
}


Jetzt habe ich mir gedacht, warum schreibe ich nicht gleich ein Array als Parameter rein. Nur weiß ich leider nicht, wie man das Array in so einem Fall auf 4 Zahlen beschränkt. Also es müsste dann irgendwie so aussehen:

private int Min(int[4] numbers)


Aber das geht wohl nicht ... ? Jedenfalls meint das Visual Studio so ...
19.06.2012
starki 603 8
3 Antworten
7
Wie wäre es mit:
private int Min(int a, int b, int c, int d)
{
return Math.Min(Math.Min(a, b), Math.Min(c, d));
}


Zu Deiner zweiten Frage: dass ein als Parameter übergebenes Array genau 4 Elemente enthalten soll, ist eine klassische Vorbedingung. Zum Prüfen von Vorbedingungen gibt es seit .NET 4 die Klasse System.Diagnostics.Contracts.Contract, die hier im Visual-Studio-Magazin vorgestellt wurde. Für Dich sähe das dann so aus:

private int Min(int[] numbers)
{
Contract.Requires(numbers != null);
Contract.Requires(numbers.Length == 4);

//...
}


Allerdings wäre dann die Frage, warum jemand diese Methode nutzen sollte, wenn er ebenso gut schreiben könnte:

using System.Linq;
...
int[] numbers;
...
int min = numbers.Min();
19.06.2012
Matthias Hlawatsch 13,2k 4 9
Danke für die Bewertung - freut mich, daß ich offenbar helfen konnte :-) Ich habe eben noch einen Hinweis auf System.Linq.Enumerable.Min() ergänzt.
Matthias Hlawatsch 20.06.2012
3
Nur kurz der Vollständigkeithalber:

Du kannst auch eine eigenen Min-Implementierung schreiben die ein Parameter-Array entgegen nimmt und dieses anstelle der .Net-Implemtierung verwenden.

public static int Min(params int[] values){
if(values.Length == 0)
throw new ArgumentException("Es wurden keine Werte übergeben", "values");

int minVal = int.MaxValue;

foreach(int val in values)
minVal = Math.Min(val, minVal);

return minVal;
}


oder:

public static int Min(params int[] values){
if(values.Length == 0)
throw new ArgumentException("Es wurden keine Werte übergeben", "values");

int minVal = int.MaxValue;
var iter = values.GetEnumerator();

while(iter.MoveNext()){
minVal = Math.Min(minVal, (int)iter.Current);
}

if(iter is IDisposable)
(iter as IDisposable).Dispose();

return minVal;
}


Ein Beispielaufruf:

int minValue = Min(7,4,5,2,6, ...);
20.06.2012
Floyd 14,5k 3 9
Floyd 14,5k 3 9
Hi Floyd, hat es eigentlich einen speziellen Grund, dass Du hier die Iteration ausprogrammierst, statt einfach

foreach(int currentValue in values)
{
minVal = Math.Min(minVal, currentValue);
}

zu schreiben?
Matthias Hlawatsch 12.07.2012
Siehe sein erstes Beispiel, dort macht er doch genau das... das zweite, ausprogrammierte Beispiel, scheint nur ergänzend (und gefällt mir persönlich obendrein auch noch)
Karill Endusa 12.07.2012
Ah stimmt - sitze gerade an einem 600px hohen Bildschirm, da war das erste Beispiel schon wieder weggescrollt. Aber warum etwas hinschreiben, was der Compiler sowieso erledigt, wenn er foreach behandelt???
Matthias Hlawatsch 12.07.2012
Hallo Matthias, das ist Rückblickend betrachtet eine gute Frage :D Ich hatte ein wenig mit IEnumerable und Yield experimentiert und da viel das dabei ab.

Wenn man die Methodensignatur auf public static int Min(IEnumerables<int> values) ändert funktioniert das obere Beispiel nicht korrekt mit Yield. Das untere schon. (Kann dir aus dem Kopf aber gerade auch nicht sagen wieso nicht)
Floyd 12.07.2012
2
So werden nicht alle Zahlen sortiert, sondern es wird nur die kleinste herausgesucht. Sollte schneller gehen, als wenn du ein Array sortierst.

int min = int.MaxValue;
if (a < min) min = a;
if (b < min) min = b;
if (c < min) min = c;
if (d < min) min = d;
return min;
19.06.2012
KN 1,7k 8
Die Zeile

int min = int.MaxValue;

kannst du durch

int min = a;

ersetzten und somit noch etwas mehr rausholen.

if (a < min) min = a;
Floyd 19.06.2012
Es fehlt immernoch ne Editierfunktion für Kommentare -.-

Die letzte Zeile meines Kommentars kann dann gestrichen werden.
Floyd 19.06.2012
Hi Floyd, da hast du schön recht :-)
KN 20.06.2012

Stelle deine .net-Frage jetzt!