2008-10-22 107 views
8

我一直在阅读ruby中的条件式表达式。然而,我遇到了一个我不明白定义经典的FizzBu​​zz问题。我了解FizzBu​​zz问题,甚至在使用三元运算符找到以下快速解决方案之前编写了自己的问题。如果有人能向我解释如何这条产业链工程,以满足FizzBu​​zz问题将是非常赞赏:)FizzBu​​zz使用三元条件运算符

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

回答

16

一些括号可能会帮助:

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

所以,如果我是被3整除,那么它检查我是否也可以被5整除。如果是,它会打印出“FizzBu​​zz”,否则就是“Buzz”。如果我不能被3整除,那么它会再次检查5的可分性,如果是,则打印“Fizz”,否则就是我。

+0

非常感谢 - 括号和你的解释已经解决了这个问题 – Damian 2008-10-22 09:58:32

1

的流动是:

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

三元是一个基本的if-then结构。

以上,相当于...

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

或者使用一些括号...

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

读不带括号的代码是让我抽搐。 – nickf 2008-10-22 09:52:36

+0

对不起。我只是懒惰。 – 2008-10-22 13:51:15

11

这是因为在这个Jeff Atwood article规定的FizzBu​​zz问题的说明。

编写打印 编号从1到100但对于三种打印“菲斯” 而不是数量 倍数和五个打印“嗡嗡”的 倍数的程序。 数字是 三个和五个打印“FizzBu​​zz”的倍数。

A ternary operator是写if-else语句的简写。一般格式为:

 
cond ? evaluate_if_cond_is_true : evaluate_if_cond_is_false 

所以,如果我写:

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

等同于下面的代码:

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

其中cond是i % 2 == 0,evaluate_if_cond_is_true是1和evaluate_if_cond_is_false是0

关于三元运算符的好处是它们可以合并。这意味着当条件评估为真或假时执行的语句可以是另一个三元操作符。

让我们把整个情况更加易于阅读的时尚:

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

这映射到if-else语句很容易与上述规则:

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

这不是有效的代码但是因为三元运算符的结果在结果表达式中被内联,所以它被用作puts命令的输入。

7

为了好玩,还有一种方法:

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

而另:

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