C# FizzBu​​zz 开关解决方案

C# FizzBuzz Switch Solution

是否可以使用 switch 构造在 C# 中创建 FizzBu​​zz 解决方案。我找到了适用于 JavaScript 和其他语言的解决方案,但这些(或等效语法)似乎不适用于 C#。

为了参考,我将 if 语句版本写在下面:

for (int x = 1; x <= 15; x++)
        {
            if (x % 5 == 0 && x % 3 == 0)
                Console.WriteLine("FizzBuzz");
            else if (x % 5 == 0)
                Console.WriteLine("Buzz");
            else if (x % 3 == 0)
                Console.WriteLine("Fizz");
            else
                Console.WriteLine(x);
        }
        Console.ReadLine();

编辑:忘记放置我的 switch 语句代码,抱歉:

for (x = 1; x <= 15; x++)
{
    switch (x)
    {
        case (x % 3 == 0 && x % 5 == 0):
            Console.WriteLine("FizzBuzz");
            break;
        case (x % 5 == 0):
            Console.WriteLine("Buzz");
            break;
        case (x % 3 == 0):
            Console.WriteLine("Fizz");
            break;
        default:
            Console.WriteLine(x);
            break;
    }
}

我的问题是模语句。对于我的每个案例,错误是 "Cannot implicitly convert type bool to int. I've tried replacing switch (x) with switch (true) but that doesn't help much, just changes the error to "需要一个常数值。

"Is it possible to create the FizzBuzz solution in C# with the switch construct"

是的,这是可能的,但不太实用(与 if 语句相比)。这是因为您打开了一个表达式,然后您的 case 语句必须将常量表达式与该值进行比较。所以你不能做 switch (0) 然后 case (i % 15) 因为 i % 15 不是常量表达式。

鉴于此,您可以打开i % 15以减少与已知基集的比较次数,然后对可被3、5和15整除的结果进行特殊处理:

for (int x = 1; x <= 15; x++)
{
    switch (x % 15)
    {
        // Evenly divisible by 15
        case 0:
            Console.WriteLine("FizzBuzz");
            break;

        // Evenly divisible by 3
        case 3:
        case 6:
        case 9:
        case 12:
            Console.WriteLine("Fizz");
            break;

        // Evenly divisible by 5
        case 5:
        case 10:
            Console.WriteLine("Buzz");
            break;

        // Everything else
        default:
            Console.WriteLine(x);
            break;
    }
}

但是 if 语句要简洁得多:

for (int x = 1; x <= 15; x++)
{
    if (x % 15 == 0) Console.WriteLine("FizzBuzz");
    else if (x % 3 == 0) Console.WriteLine("Fizz");
    else if (x % 5 == 0) Console.WriteLine("Buzz");
    else Console.WriteLine(x);
}

可以将 fizzbuzz 写成一个简单的开关。

它和 if else 一样快。我对此有点着迷,并创建了一个小基准并将其上传到 git:https://github.com/chrisaddams/fizzbuzz-everyway-c-sharp

我查到的速度结果如下:

Average Speed of Switch  is             63.46 ms
Average Speed of IfElseCont is          62.03 ms
Average Speed of If Else is             60.62 ms
Average Speed of If Only is             73.35 ms
Average Speed of If Cont is             73.55 ms

无论如何,这是代码,我认为这是一个非常简洁易读的解决方案。

using System.Diagnostics;
using System;
namespace fizzbuzz
{
    class fizzyCase
    {
        static void Main(string[] args)
        {
            Stopwatch timer = new Stopwatch();
            timer.Start();
            for (int i = 0; i <= 10000; i++)
            {
                switch (true)
                {
                    case var FizzBuzz when (i % 15 == 0):
                        Console.WriteLine("fizzbuzz");
                        break;
                    case var Fizz when (i % 3 == 0):
                        Console.WriteLine("fizz");
                        break;
                    case var Buzz when (i % 5 == 0):
                        Console.WriteLine("buzz");
                        break;
                    default:
                        Console.WriteLine(i);
                        break;
                }
            }
            timer.Stop();
            Console.WriteLine("Elapsed:{0}milliseconds", timer.Elapsed.TotalMilliseconds);

        }
    }
}

此解决方案使用在 C# 8.0 中实现的 switch 表达式。允许非常简洁的代码。它还使用本地 static 方法(自版本 8.0 起也可用):

public static void FizzBuzz(int n)
{
    for (var i = 0; i <= n; ++i)
    {
        var res = i switch
        {
            var x when is5(x) && is3(x) => "FizzBuzz",
            var x when is5(x) => "Fizz",
            var x when is3(x) => "Buzz",
            _ => i.ToString()
        };

        Console.WriteLine(res);
    }

    static bool is3(int x)
    {
        return x % 3 == 0;
    }
    static bool is5(int x)
    {
        return x % 5 == 0;
    }
}

像其他人一样,我会在 switch 语句上使用 switch 表达式。但是,我发现使用 tuple pattern 清洁剂:

static string FizzBuzz(int i)
{
     return (i % 3, i % 5) switch
     {
         (0, 0) => "FizzBuzz",
         (0, _) => "Fizz",
         (_, 0) => "Buzz",
         (_, _) => i.ToString()
     };
 }