2008-10-22 14 views
8

Ich habe gelesen auf bedingten Stil Ausdrücke in Ruby. Allerdings stieß ich auf eine, die ich nicht ganz verstehen konnte, um das klassische FizzBuzz-Problem zu definieren. Ich verstehe das FizzBuzz-Problem und schrieb sogar mein eigenes, bevor ich die folgende schnelle Lösung unter Verwendung des ternären Operators fand. Wenn jemand kann mir erklären, wie diese Kette das FizzBuzz Problem gerecht zu werden arbeitet wäre es sehr geschätzt :)FizzBuzz mit ternären Bedingungsoperator

for i in 0...100 
    puts i%3==0 ? i%5==0 ? "FizzBuzz" : "Buzz" : i%5==0 ? "Fizz" : i 
end 

Antwort

16

Einige Klammern helfen könnten:

puts (i%3 == 0) ? ((i%5 == 0) ? "FizzBuzz" : "Buzz") : ((i%5 == 0) ? "Fizz" : i) 

Also, wenn ich durch 3 teilbar ist , dann prüft es, ob ich auch durch 5 teilbar ist. Wenn ja, druckt es "FizzBuzz", sonst nur "Buzz". Wenn ich nicht durch drei teilbar ist, prüft es die Teilbarkeit erneut um 5 und druckt "Fizz" wenn ja, sonst nur ich.

+0

Vielen Dank - die Klammer und Ihre Erklärung aufgelöst hat dieses Problem – Damian

1

die Strömung ist:

if (i%3 == 0) {    // multiple of 3 
    if (i%5 == 0) {   // multiple of 3 and 5 
     puts "FizzBuzz" 
    } else {     // not multiple of 5, only of 3 
     puts "Buzz" 
    } 
} else (     // not multiple of 3 
    if (i%5 == 0) {   // multiple of 5, not of 3 
     puts "Fizz" 
    } else {     // multiple of neither 5 nor 3 
     puts i 
    } 
} 
3

Die ternäre ist eine grundlegende if-then-Struktur.

die oben entspricht ...

if i%3 ==0 
    if i%5 == 0 
     "FizzBuzz" 
    else 
     "Buzz" 
else 
    if i%5 == 0 
     "Fizz" 
    else 
     i 

Oder einige Pars mit ...

puts i%3==0 ? (i%5==0 ? "FizzBuzz" : "Buzz") : (i%5==0 ? "Fizz" : i) 
+1

lesen, dass Code ohne Klammern macht mich zucken . – nickf

+0

Entschuldigung. Ich war nur faul. –

+0

Vorgeben, es ist Pseudocode. ;-) – Wickethewok

11

Hier eine Beschreibung des FizzBuzz Problem ist, wie in diesem Jeff Atwood article angegeben.

Schreiben Sie ein Programm, das die Zahlen von 1 bis 100. Aber für ein Vielfaches von drei print „Fizz“ anstelle der Anzahl und für die Vielfache von fünf print „Buzz“ druckt. Für Zahlen, die Vielfache von beiden sind drei und fünf drucken "FizzBuzz".

Eine ternary operator ist eine Kurzschrift für eine if-else-Anweisung. Das allgemeine Format ist:

 
cond ? evaluate_if_cond_is_true : evaluate_if_cond_is_false 

Also, wenn ich schreibe:

int isEven = (i % 2 == 0) ? 1 : 0; 

entspricht dem folgenden Code:

if (i % 2 == 0) { 
    isEven = 1; 
} else { 
    isEven = 0; 
} 

Wo cond i % 2 == 0 ist, evaluate_if_cond_is_true ist 1 und evaluate_if_cond_is_false ist 0 .

Das Schöne an ternären Betreibern ist, dass sie kombiniert werden können. Dies bedeutet, dass die Anweisung, die ausgeführt wird, wenn eine der beiden Bedingungen wahr oder falsch ist, ein anderer ternärer Operator sein kann.

Let setzten den gesamten Zustand in einer besser lesbaren Art und Weise:

i%3==0 ? 
    i%5==0 ? 
     "FizzBuzz" 
     : "Buzz" 
    : i%5==0 ? 
     "Fizz" 
     : i 

Und diese Zuordnung zu if-else-Anweisungen sind leicht mit den Regeln oben erklärt:

if (i%3==0) { 
    if (i%5==0) { 
     "FizzBuzz" 
    } else { 
     "Buzz" 
    } 
} else { 
    if (i%5==0) { 
     "Fizz" 
    } else { 
     i 
    } 
} 

Dies gilt nicht, Code Da das Ergebnis des ternären Operators jedoch im Ergebnisausdruck inline ist, wird es als Eingabe für den Befehl puts verwendet.

7

Für Spaß, hier ist eine andere Art und Weise:

puts (1..100).map {|i| (fb = [["Fizz"][i%3],["Buzz"][i%5]].compact.join).empty? ? i : fb} 

Und ein anderer:

(1..100).zip([nil,nil,"Fizz"]*34,[nil,nil,nil,nil,"Buzz"]*20).map {|a,b,c| b || c ? [b,c].join : a} 
+1

Das ist falsch. Die Spezifikation besagt, dass Sie die Nummer nur ausdrucken sollten, wenn Sie kein Fizz oder Buzz drucken. – mxcl

+0

Ah, wahr genug. –