问题
When solving "fizz-buzz" in C# using a "while" loop, I found out that first I should find the multiples of both 3 and 5 (multiples of 15) and then go to the multiples of 3 and 5 like below.
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);
}
}
But if I write the code to filter multiples of 3 and 5 first and then go to the multiples of both 3 and 5 (multiples of 15) like below the end result only shows the fizz (multiples of 3) and buzz (multiples of 5) without fizz-buzz (multiples of both 3 and 5). Does anyone know what's the reason for this even IDE doesn't show me any errors.
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);
}
}
回答1:
This boils down to the fact that if-else
statements are processed sequentially. As soon as a condition that evaluates to true
is encountered, the other else if
clauses are skipped.
Suppose that a
and b
are both true
. When you write
if (a) {
Foo1();
}
else if (b) {
Foo2();
}
you do not execute both Foo1
and Foo2
. Since a
is true
, Foo1
executes and b
is not even evaluated.
Now consider your problem. Consider the number 15. All three candidate divisors, 3, 5 and 15, divide into that number.
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);
}
Since the multiples of 15
are also multiples of 3
(and 5
), you will never even reach the myval % 15 == 0
test for multiples of 15
.
回答2:
Because it satisfies the first two conditions. So it will never hit your third else statement.
回答3:
It's because something divisible by 3 and 5 is also divisible by 3 and by 5. If you catch either of those conditions first, the later condition is never checked.
You could also write it like so:
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);
This will print all conditions without needing a separate check for % 15.
Also, I know this wasn't the original question, but typically someone wouldn't use a while
loop to cycle through a range of numbers. Use a for
loop for that:
for( int myval = 0; myval <= 100; myval++)
{
// code goes here
}
回答4:
I always solved this a slightly different way: by constructing the string to add.
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);
}
回答5:
You can use this method to fill your 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 );
}
来源:https://stackoverflow.com/questions/16611626/understanding-the-fizz-buzz-in-c-sharp