2010-10-21 6 views
17

Ich lese ein C# -Buch für Anfänger, und an jedem Ende des Kapitels gibt es Übungen, die basierend auf den behandelten Lektionen beantwortet werden.Ist es möglich, diesen Code in LINQ auszudrücken?

Eine dieser Übungen geht so: (nicht die genauen Formulierungen)

Schreiben Sie ein Programm, das ein int als Feldlänge, und die Werte für das Array akzeptiert.
Dann wird gedruckt:
"" wenn das Array nicht aufsteigend sortiert ist.
"", wenn es sortiert ist. Und,
"" wenn es sortiert ist, aber es gibt Duplikate.

Beispiel:

// Sorted 
Input: 1, 2, 3, 5 
Print: 1 

// Not sorted 
Input: 2, 1, 3, 6 
Print: 0 

// Sorted, but with duplicates 
Input: 2, 2, 3, 7 
Print: 2 

Ich weiß nicht, ob meine Logik hier absolut, aber irgendwie funktioniert,
und ich es in meinem Weg mit diesem Code gemacht:

int arrayLength = 0; 
int prev, next; 
int sortStatus = 1; 

Console.Write("Input array Length: "); 
arrayLength = Convert.ToInt32(Console.ReadLine()); 
int[] ar = new int[arrayLength]; 

for (int x = 0; x < arrayLength; x++) 
{ 
    Console.Write("Input {0} value: ", (x+1).ToString()); 
    ar[x] = Convert.ToInt32(Console.ReadLine()); 
} 

for (int x = 0; x < ar.Length-1; x++) 
{ 
    prev = (int)ar[x]; 
    next = (int)ar[x + 1]; 

    if (next < prev) 
     sortStatus = 0; 
    if (next == prev) 
     sortStatus = 2; 
} 

Console.Write(sortStatus.ToString()); 
Console.Read(); 

Ist es möglich, dies in LINQ auszudrücken? Wie?

+3

+1 für eine gut strukturierte Frage zu stellen, sowie zu wollen wissen, wie zu verbessern, was Sie bereits getan haben. – RPM1984

+0

@ RPM1984: Danke Herr :) – yonan2236

+0

Angesichts der Tatsache, dass der eigentliche Code, der die 'isSorted' Logik enthält weniger als 10 Zeilen lang (und sollte eigentlich in einer eigenen Methode sein), wollen Sie wirklich eine gewundene LINQ-Anweisung zu ersetzen? –

Antwort

17
if (ar.SequenceEqual(ar.OrderBy(x => x))) 
{ 
    if (ar.Distinct().Count() == ar.Length) 
     return 1; 
    else 
     return 2; 
} 
else 
{ 
    return 0; 
} 
+0

Danke, Sir, ich werde versuchen, Ihre ... – yonan2236

+0

Ja, das ist der Weg zu gehen. Gute Arbeit. +1 – RPM1984

+0

es funktioniert Sir ... :) danke. – yonan2236

5

Eine reine LINQ Alternative ... (für akademisches Interesse nur (aber wahrscheinlich immer noch schneller als die akzeptierten Antwort!)

var input = new int[] { 1, 2, 3, 4, 5 }; 

var output = input.Zip(input.Skip(1), (a, b) => new {a=a, b=b}) 
       .Aggregate(1, (status, x) => status == 0 ? 0 : ((x.a > x.b ? 0 : (x.a == x.b ? 2 : status)))); 
+0

Hmm .. was ist 'Eingang' hier? Ist es mein Array? – yonan2236

+0

Ja, Eingabe wäre Ihr Array. –

+0

danke Sir für Ihre Version der Antwort :) – yonan2236

3

Als Hinweis, Ihre ausgedrückt nicht-LINQ-Logik hat einen Fehler

.
if (next < prev) 
    sortStatus = 0; 
if (next == prev) 
    sortStatus = 2; 

Ihre Regel besagt, dass das Array aufsteigend sortiert werden müssen, haben aber Duplikate, um eine Leistung von 2 jedoch zu erhalten, wird Ihre Logik 2 zurückkehren für { 1, 9, 7, 7 }.

Eine andere Möglichkeit, Ihren Code zu schreiben, könnte folgender sein. (Dies ist nicht LINQ verwenden, aber das ist zu lang als Kommentar auf Ihre Frage zu stellen.)

static int EvaluateArray(int[] array) 
{ 
    int? lastItem = null; 
    bool match = false; 
    foreach (int item in array) 
    { 
     if (item < lastItem) 
      return 0; 
     else if (item == lastItem) 
      match = true; 

     lastItem = item; 
    } 

    if (match) 
     return 2; 

    return 1; 
} 

Bei dieser Methode werden wir früh zurück, sobald wir ein Element weniger als die vorherigen Artikel haben . Andernfalls setzen wir einen booleschen Wert, wenn wir auf einen übereinstimmenden Wert stoßen. Am Ende der Schleife wissen wir, dass das Array aufsteigend sortiert ist. Das einzige, was übrig bleibt, ist zu überprüfen, ob es ein Match gab.

+0

Vielen Dank für meinen Fehler. Ich werde daraus lernen. – yonan2236

+0

Sir nur eine Frage, in Ihrem Code oben, was bedeutet dieses Code-Snippet? "Int? lastItem = null; '. Das '"? "' Ding dort ... – yonan2236

+2

@yonan: Das ist Kurzschrift für 'Nullable '. C# 2 führte das Konzept der nullbaren Werttypen ein. Normale Werttypen wie "int" können nicht auf null gesetzt werden, was dazu führte, dass Entwickler "magische" Werte verwenden, um häufig "kein Wert" zu bedeuten. (Betrachte 'string.IndexOf (substring)' gibt -1 zurück, wenn der Teilstring nicht innerhalb des Strings gefunden wird.) Mit 'Nullable ' haben wir jetzt eine Möglichkeit, tatsächlich anzuzeigen, dass etwas keinen Wert hat. In C# können wir das mit Kurzschrift ausdrücken. 'int?' ist eine Abkürzung für 'Nullable ' ähnlich wie 'int' ist eigentlich C# für' Int32'. –

0

Nicht getestet.

IEnumerable<int> signs = 
    from i in Enumerable.Range(0, ar.Length).Skip(1) 
    select ar[i-1].CompareTo(ar[i]); 

int result = 
    signs.Any(sign => sign < 0) ? 0 : 
    signs.All(sign => 0 < sign) ? 1 : 
    2; 

auch ungetestete:

int minSign = !ar.Skip(1).Any() ? 1 : 
(
    from i in Enumerable.Range(0, ar.Length).Skip(1) 
    select ar[i-1].CompareTo(ar[i]) 
).TakeWhile(x => 0 <= x).Min(); 

int result = 
    minSign < 0 ? 0 : 
    0 < minSign ? 1 : 
    2; 
+0

Bitte verzeihen Sie meine ASCII-Kunst ... eigentlich, lassen Sie mich wissen, wenn dieses Bit ist verwirrend - (x => 0 <= x) –

+0

danke für die Antwort :) – yonan2236

Verwandte Themen