Fizz buzz程序奇怪的输出?

时间:2014-01-13 11:11:25

标签: c#

为什么这会导致1 2 Fizz 3?不应该导致1 2 Fizz ?!我对这个循环的输出有点困惑..?添加其他如果删除此问题,我的问题是为什么?

for (int i = 1; i <= value; i++)
{
    if (i % 3 == 0)
    {
        ViewBag.Output += "Fizz ";
    }
    if (i % 5 == 0)
    {
        ViewBag.Output += "Buzz ";
    }
    else
    {
        ViewBag.Output += i.ToString() + " ";
    }
}

3 个答案:

答案 0 :(得分:5)

如果第一个if匹配,则不会跳过迭代。因此,如果在当前else未除以5的情况下评估了块,则i % 5 i部分为 for (int i = 1; i <= value; i++) { if (i % 3 == 0) ViewBag.Output += "Fizz "; if (i % 5 == 0) ViewBag.Output += "Buzz "; if ((i % 3 != 0) && (i % 5 != 0)) ViewBag.Output += i.ToString() + " "; } 部分:

else

现在使用常见 for (int i = 1; i <= value; i++) { if (i % 3 == 0) { ViewBag.Output += "Fizz "; if (i % 5 == 0) ViewBag.Output += "Buzz "; } else if (i % 5 == 0) { ViewBag.Output += "Buzz " } else // neither divided by 3 nor by 5 { ViewBag.Output += i.ToString() + " "; } } 块的替代解决方案:

var valuesToCheck = new Dictionary<int, string> {
    { 3, "Fizz" },
    { 5, "Buzz" }
};

for (int i = 1; i <= value; i++)
{
     bool divisorFound = false;

     foreach(var kvp in valuesToCheck)
     {
         if (i % kvp.Key == 0)
         {
             divisorFound = true;
             ViewBag.Output += kvp.Value + " ";
         }
     }

     if (!divisorFound)
         ViewBag.Output += i + " ";
}

还有一个字典解决方案,以避免所有这些额外的if ... else检查:

{{1}}

答案 1 :(得分:1)

这是因为您的第二个if被评估,无论第一个if的结果如何。

因此,当i == 3时,第一个if评估为true,第二个评估为false,因此第二个if评估else块被执行。

答案 2 :(得分:1)

执行第二个if,无论前一个if如何,因此您应该预期输出。


这是从@KonradRudolph answer to a previous question获取FizzBu​​zz问题的简单解决方案

for (int i = 1; i <= value; i++)
    ViewBag.Output +=
        i % 15 == 0 ? "FizzBuzz " :
        i % 3 == 0 ? "Fizz " :
        i % 5 == 0 ? "Buzz " : 
        i.ToString() + " ";

或者,或者。

string FizzBuzz(int value, int a = 3, int b = 5)
{
    if value % (a * b) == 0 return "FizzBuzz";
    if value % a == 0 return "Fizz";
    if value % b == 0 return "Buzz";
    return value.ToString();
}

用于,

viewBag.Output = string.Join(" ", Enumerable.Range(1, value).Select(FizzBuzz));

或超越理性

IEnumerable<string> Checker<T>(
        this IEnumerable<T> source,
        params KeyValuePair<Predicate<T>, string>>[] checks)
(
    var found = false;
    foreach(var t int source)
    {
        var result =
            string.Concat(checks.Where(c => c.Key(t)).Select(c => c.Value));
        if (result.IsNullOrEmpty())
        {
            yield return t.ToString();
            continue;
        }

        yield return result;
    }
)

可以像这样使用,

ViewBag.Output = string.Join(" ", Enumerable.Range(1, value).Checker(
    new KeyValuePair<Predicate<T>, string>>(i => i % 3 == 0, "Fizz"),
    new KeyValuePair<Predicate<T>, string>>(i => i % 5 == 0, "Buzz"));