【问题标题】:C# FizzBuzz Switch SolutionC# FizzBu​​zz 开关解决方案
【发布时间】:2018-09-06 17:18:26
【问题描述】:

是否可以使用 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;
    }
}

我的问题是模数语句。错误是“无法将类型 bool 隐式转换为 int。我尝试将 switch (x) 替换为 switch (true) 但这并没有多大帮助,只是将错误更改为我的每个案例的“预期值为常量”。

【问题讨论】:

  • 如果它适用于if,它适用于switch,请向我们展示您尝试过的开关的代码。
  • 网上有很多这样的例子,因为这是一个通用的编程难题。
  • 提示:以switch(x%15)开头。现在最多只有15个案例。他们是谁?
  • @WilomGfx 这种说法在一般情况下是不正确的。您可以使用 if 执行某些逻辑,而使用 switch 则无法执行此操作,即使使用新的模式匹配也是如此。
  • switch 的参数和case 的参数必须解析为相同的类型。您正在“切换”int,然后封装 bool

标签: c# switch-statement fizzbuzz


【解决方案1】:

此解决方案使用在 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;
    }
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      “是否可以在 C# 中使用 switch 构造创建 FizzBu​​zz 解决方案”

      是的,这是可能的,但不是很实用(与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);
      }
      

      【讨论】:

      • 所以,如果我理解正确,如果我想修改 for 循环到 100 而不是 15,我将不得不添加 3、6、9、12、18、21、24。 .. 对于可被 3 整除的情况,他手动与 5 和 15 相同?
      • 不,你试过了吗? switch (x % 15) 将数字减少到除以 15 的余数。因此,这将适用于您喜欢的尽可能多的迭代。
      • 哦,是的,你是对的。对不起,我正在工作,所以我实际上还没有机会坐下来尝试一下。我只是以某种方式读错了代码,现在我明白你的意思了。谢谢!
      • 没问题,很高兴它有帮助!
      【解决方案4】:

      可以将 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);
      
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-25
        • 2012-03-16
        • 2012-09-02
        相关资源
        最近更新 更多