2013-05-17 47 views
0

在C#中使用“while”循环解决“嘶嘶声”时,我发现首先应该找到3和5的倍数(15的倍数),然后转到3和5的倍数如下。了解C#中的嘶嘶声#

int myval = 0; 

while (myval < 100) 
{ 
    myval = myval + 1; 

    if (myval % 15 == 0) 
    { 
     listBox1.Items.Add("fizzbuzz"); 
    } 
    else if (myval % 3 == 0) 
    { 
     listBox1.Items.Add("fizz"); 
    } 
    else if (myval % 5 == 0) 
    { 
     listBox1.Items.Add("buzz"); 
    } 
    else 
    { 
     listBox1.Items.Add(myval); 
    } 
} 

但是如果我编写代码来过滤器3和5的第一倍数,然后去既3和5(15的倍数)之类的最终的结果下面的倍数仅示出了3嘶嘶声(倍数)和嗡嗡声(5的倍数),没有嘶嘶声(3和5的倍数)。有谁知道这是什么原因,即使IDE没有显示任何错误。

myval = 0; 

while (myval < 100) 
{ 
    myval = myval + 1; 

    if (myval % 3 == 0) 
    { 
     listBox1.Items.Add("fizz"); 
    } 
    else if (myval % 5 == 0) 
    { 
     listBox1.Items.Add("buzz"); 
    } 
    else if (myval % 15 == 0) 
    { 
     listBox1.Items.Add("fizzbuzz"); // for multiples of both 3 and 5 
    } 
    else 
    { 
     listBox1.Items.Add(myval); 
    } 
} 

end result without fizz-buzz multiples of both 3 and 5

+2

预期的代码运行。由于您正在使用else,因此您不允许多个逻辑决策。 – emd

+0

你能解释一下,只有改变“if语句”才能正确写出它吗 – scylla

+0

@scylla我相信你能够自己阅读和理解下面的许多答案,不是吗?如果没有,我们还应该告诉你什么? – Nolonar

回答

4

这归结于if-else语句顺序地处理这一事实。一旦遇到评估为true的条件,则跳过其他else if子句。

假设ab都是true。当你写

if (a) { 
    Foo1(); 
} 
else if (b) { 
    Foo2(); 
} 

你不执行这两个Foo1Foo2。由于atrue,因此Foo1执行且b未被评估。

现在考虑你的问题。考虑数字15.所有三个候选除数,3,5和15分成这个数字。

if (myval % 3 == 0) 
{ 
    listBox1.Items.Add("fizz"); 
} 
else if (myval % 5 == 0) 
{ 
    listBox1.Items.Add("buzz"); 
} 
else if (myval % 15 == 0) 
{ 
    listBox1.Items.Add("fizzbuzz"); // for multiples of both 3 and 5 
} 
else 
{ 
    listBox1.Items.Add(myval); 
} 

由于15倍数也都是3(和5)的整数倍,你甚至不会达到myval % 15 == 0测试的15倍数。

+0

但是有没有办法通过只改变“if-else语句”而不改变倍数的顺序来纠正这一点。 – scylla

+1

如果你想做一个简单的'if ... else if ... else if ...',那么你需要小心订单。你可以这样做,'if(isFizz &&!isBuzz)'类型的方法,但是更复杂。这个问题本身就很复杂。 –

6

因为它满足前两个条件。所以它不会打你的第三个陈述。

+1

+1,OP需要先检查'myval%15',然后从那里下移 –

+1

@JensKloster - 是的。经典面试问题:) –

+0

看起来这是最简单的方法。谢谢你Jens! – scylla

2

这是因为被3和5整除的东西也可以被3和5整除。如果你首先遇到这两个条件中的任何一个,那么后面的条件就不会被检查。

你也可以把它写像这样:

var resultString = ""; 
if(myval % 3 == 0) resultString += "fizz"; 
if(myval % 5 == 0) resultString += "buzz"; 
if(myval % 5 != 0 && myval % 3 != 0) resultString += myval; 
listBox1.Items.Add(resultString); 

这将打印的所有条件,而不需要单独的支票%15

另外,我知道这是不是原来的问题,但通常有人不会使用循环来遍历一系列数字。使用for循环为:

for(int myval = 0; myval <= 100; myval++) 
{ 
    // code goes here 
} 
1

我总是这解决了一个稍微不同的方式:通过构建字符串添加。

for (int myVal = 0; myVal < 100; myVal++) 
{ 
    string fb = ""; 

    if ((myVal % 3) == 0) { fb = "fizz"; } 
    if ((myVal % 5) == 0) { fb += "buzz"; } 

    // Handle the case where it isn't divisible by 3 or 5: 
    if (fb == "") { fb = myVal.ToString(); } 

    // "output" the string. 
    listBox1.Items.Add(fb); 
} 
+1

看起来你错过了数字可以被3或5整除的情况。 – Chris

+1

我修正了代码。只需要首先进行同行评审。 – Nolonar

+1

看起来像我建议的编辑被拒绝...这是我改变了:'if(fb!=“”){listBox1.Items.Add(fb); }'改为:'if(fb ==“”){fb = myVal.ToString(); } listBox1.Items.Add(fb);' – Nolonar

0

您可以使用此方法来填补你的Listbox

foreach (int i in Enumerable.Range(1,100)){ 
     string str = null; 
     listBox1.Items.Add((str = (i % 3 == 0 ? "fizz" : "") 
           + (i % 5 == 0 ? "buzz" : "")) == "" 
           ? i.ToString() : str); 
    }