C# 写 FizzBu​​zz

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11764539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 19:08:47  来源:igfitidea点击:

Writing FizzBuzz

c#optimizationfizzbuzz

提问by Mare Infinitus

Reading the coding horror, I just came across the FizzBuzz another time.

阅读编码恐怖,我刚刚又遇到了 FizzBu​​zz。

The original post is here: Coding Horror: Why Can't Programmers.. Program?

原帖在这里:编码恐怖:为什么程序员不能......编程?

For those who do not know: FizzBuzz is a quite popular children's game. Counting from 1 to 100, and every time a number is divisible by 3 the string "Fizz" is called, every time a number is divisible by 5 the string "Buzz" is called and every time a number is divisible by 3 and 5 both strings together "FizzBuzz" are called instead of the number.

对于那些不知道的人:FizzBu​​zz 是一款非常受欢迎的儿童游戏。从 1 数到 100,每次一个数能被 3 整除时,调用字符串“Fizz”,每次一个数能被 5 整除时,调用字符串“Buzz”,并且每次一个数都能被 3 和 5 整除将“FizzBu​​zz”串在一起称为“FizzBu​​zz”而不是数字。

This time, I wrote the code and it took me a minute, but there are several things that I do not like.

这一次,我写了代码,花了我一分钟,但有几个我不喜欢的地方。

Here is my code:

这是我的代码:

public void DoFizzBuzz()
{
    var combinations = new Tuple<int, string>[] 
    { 
        new Tuple<int, string> (3, "Fizz"), 
        new Tuple<int, string> (5, "Buzz"), 
    };

    for (int i = 1; i <= 100; ++i)
    {
        bool found = false;

        foreach (var comb in combinations)
        {
            if (i % comb.Item1 == 0)
            {
                found = true;
                Console.Write(comb.Item2);
            }
        }

        if (!found)
        {
            Console.Write(i);
        }

        Console.Write(Environment.NewLine);
    }
}

So my questions are:

所以我的问题是:

  1. How do I get rid of the bool found?
  2. Is there a better way of testing than the foreach?
  1. 我如何摆脱发现的布尔值?
  2. 有没有比 foreach 更好的测试方法?

采纳答案by Rob H

I think what you're trying to accomplish is a generic solution to FizzBuzz, that will work for any number of number-word combinations.

我认为您要完成的是 FizzBu​​zz 的通用解决方案,它适用于任意数量的数字-单词组合。

You have a good start - I think I can answer your questions with this example:

你有一个好的开始 - 我想我可以用这个例子回答你的问题:

public void DoFizzBuzz()
{
    var combinations = new List<Tuple<int, string>>
    { 
        new Tuple<int, string> (3, "Fizz"), 
        new Tuple<int, string> (5, "Buzz"), 
    };

    Func<int, int, bool> isMatch = (i, comb) => i % comb == 0;
    for (int i = 1; i <= 100; i++)
    {
        Console.Write(i);

        var matchingCombs = combinations.Where(c => isMatch(i, c.Item1)).ToList();
        if (matchingCombs.Any())
        {
            Console.Write(string.Join("", matchingCombs.Select(c => c.Item2)));
        }
        else
        {
            Console.Write(i);
        }
        Console.Write(Environment.NewLine);
    }
}

In practice, you would pass combinationsin to the method, but I included it inside just to be concise.

在实践中,您会传入combinations该方法,但为了简洁起见,我将其包含在其中。

回答by Hogan

3rd edit:

第三次编辑:

Here is one way to "get rid of the bool" from your version (that is replace the for loop in your original question with this):

这是从您的版本中“摆脱 bool”的一种方法(即用此替换原始问题中的 for 循环):

for (int i = 1; i <= 100; i++)
{
  var x = combinations.Where(n => i % n.Item1 == 0);

  if (x.Count() == 0)
    Console.Write(i);
  else
    Console.Write(string.Join("",x.Select(e => e.Item2)));

  Console.Write(Environment.NewLine);
}


Prior answers:

之前的回答:

For a pure C# solution check out Keith Thompson'ssolution.

对于纯 C# 解决方案,请查看Keith Thompson 的解决方案。

using System;
class FizzBuzz {
    static void Main() {
        for (int n = 1; n <= 100; n ++) {
            if (n % 15 == 0) {
                Console.WriteLine("FizzBuzz");
            }
            else if (n % 3 == 0) {
                Console.WriteLine("Fizz");
            }
            else if (n % 5 == 0) {
                Console.WriteLine("Buzz");
            }
            else {
                Console.WriteLine(n);
            }
        }
    }
}

I worked a bit on FixBuzz using linq. These are the solutions I came up with -- I believe they represent the best way to express the solution to this problem using Linq. (GitHub)

我使用 linq 在 FixBuzz 上做了一些工作。这些是我想出的解决方案——我相信它们代表了使用 Linq 表达这个问题的解决方案的最佳方式。( GitHub)

using System;
using System.Linq;

class FizzBuzz {
  static void Main() {
    var list = Enumerable.Range(1,100)
                .Select(n => {
                      if (n % 15 == 0) {
                        return "FizzBuzz";
                      }
                      if (n % 3 == 0) {
                        return "Fizz";
                      }
                      if (n % 5 == 0) {
                        return "Buzz";
                      }
                      return n.ToString();
                    });

    foreach(string item in list)
      Console.WriteLine(item);
  }
}

and the crazy one line version:

和疯狂的单行版本:

using System;
using System.Linq;

class FizzBuzz {
    static void Main() {
      Console.WriteLine(
      String.Join(
        Environment.NewLine,
        Enumerable.Range(1, 100)
          .Select(n => n % 15 == 0 ? "FizzBuzz" 
                     : n % 3 == 0 ? "Fizz" 
                     : n % 5 == 0 ? "Buzz" 
                     : n.ToString())
      ));
    }
}

回答by Thomas Levesque

I think your implementation is unnecessarily complex. This one does the job and is easier to understand:

我认为您的实施不必要地复杂。这个可以完成工作并且更容易理解:

public void DoFizzBuzz()
{
    for (int i = 1; i <= 100; i++)
    {
        bool fizz = i % 3 == 0;
        bool buzz = i % 5 == 0;
        if (fizz && buzz)
            Console.WriteLine ("FizzBuzz");
        else if (fizz)
            Console.WriteLine ("Fizz");
        else if (buzz)
            Console.WriteLine ("Buzz");
        else
            Console.WriteLine (i);
    }
}

回答by SageMage

I recommend using the ++i instead of the i++ in a for loop because i++ requires a copy to be made ;)

我建议在 for 循环中使用 ++i 而不是 i++,因为 i++ 需要制作副本;)

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

回答by Jason Down

public void DoFizzBuzz()
{
    for (int i = 1; i <= 100; i++)
    {
        if (i % 3 == 0)
            Console.Write("Fizz");
        if (i % 5 == 0)
            Console.Write("Buzz");
        if (!(i % 3 == 0 || i % 5 == 0))
            Console.Write(i);

        Console.Write(Environment.NewLine);
    }
}

This gets rid of the bool found, but forces you to do duplicate evaluation. It is slightly different from some of the other answers using i % 15 == 0for the FizzBuzz qualification. Whether or not this is better is up for debate. However, it is a differentway.

这摆脱了 bool found,但迫使您进行重复评估。它与i % 15 == 0用于 FizzBu​​zz 资格的其他一些答案略有不同。这是否更好还有待商榷。然而,这是一种不同的方式。

回答by MikeP

Take advantage of conditional format specifiers to get a nicely golfed version:

利用条件格式说明符来获得一个很好的高尔夫球版本:

public void DoFizzBuzz()
{
    for(int i=1;i<101;i++)Console.WriteLine("{0:#;}{1:;;Fizz}{2:;;Buzz}",i%3*i%5==0?0:i,i%3,i%5);
}

回答by TheBuzzSaw

The FizzBuzz question is a great interview question. We have started using it in our interview process. It is astoundinghow many people cannot solve such a simple problem.

FizzBu​​zz 问题是一个很好的面试问题。我们已经开始在面试过程中使用它。如此简单的问题,竟然有这么多人解决不了,真是令人震惊

Keep in mind, the original blog post was eventually locked due to a flood of people posting more solutions. Hahaha.

请记住,由于大量人发布了更多解决方案,原始博客文章最终被锁定。哈哈哈。

Regardless, here is mine in C++! ^_^

无论如何,这是我的 C++!^_^

#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
    for (int i = 1; i <= 100; ++i)
    {
        bool isMultipleOfThree = (i % 3) == 0;
        bool isMultipleOfFive = (i % 5) == 0;

        if (isMultipleOfThree) cout << "Fizz";
        if (isMultipleOfFive) cout << "Buzz";
        if (!isMultipleOfThree && !isMultipleOfFive) cout << i;

        cout << '\n';
    }

    return 0;
}

回答by Wug

Unrolled for maximum efficiency. This program can outfizzbuzz all others.

展开以获得最大效率。这个程序可以超越所有其他程序。

public void FizzBuzz()
{
    const string FIZZ = "Fizz";
    const string BUZZ = "Buzz";
    const string FIZZBUZZ = "FizzBuzz";

    int i = 0;
    while (i < 150)
    {
        Console.WriteLine(++i);
        Console.WriteLine(++i);
        Console.WriteLine(FIZZ); ++i;
        Console.WriteLine(++i);
        Console.WriteLine(BUZZ); ++i;
        Console.WriteLine(FIZZ); ++i;
        Console.WriteLine(++i);
        Console.WriteLine(++i);
        Console.WriteLine(FIZZ); ++i;
        Console.WriteLine(BUZZ); ++i;
        Console.WriteLine(++i);
        Console.WriteLine(FIZZ); ++i;
        Console.WriteLine(++i);
        Console.WriteLine(++i);
        Console.WriteLine(FIZZBUZZ); ++i;
    }
}

回答by grahamesd

The original questions were: 1.How to get rid of the bool found? 2.Is there a better way of testing than the foreach?

原来的问题是: 1.How to get away the bool found? 2.有没有比foreach更好的测试方式?

This gets rid of the bool and the foreach, and I think it's still readable.

这摆脱了 bool 和 foreach,我认为它仍然可读。

public static void DoFizzBuzz()
{
    var combinations = new Tuple<int, string>[]  
    {  
        new Tuple<int, string> (3, "Fizz"),  
        new Tuple<int, string> (5, "Buzz"),  
    };

    for (int i = 1; i <= 100; i++)
    {
        var fb = combinations.Where(t => {
            if (i % t.Item1 == 0)
            {
                Console.Write(t.Item2);
                return true;
            }
            return false;
        }).ToList();

        if (!fb.Any())
        {
            Console.Write(i);
        }

        Console.Write(Environment.NewLine);
    }
} 

Who'd a thunk we'd be getting so excited about a simple kids game? :)

谁会因为一个简单的儿童游戏而让我们如此兴奋?:)

回答by Mare Infinitus

With the input of Rob H and Jacob Krall here is what I have at the moment. Perhaps I will play around with that in future... just wanted to provide it.

在 Rob H 和 Jacob Krall 的帮助下,这就是我目前所拥有的。也许我将来会玩这个……只是想提供它。

public void DoFizzBuzz()
{
    // expect this to come in as parameter
    var combinations = new Tuple<int, string>[] 
    { 
        new Tuple<int, string> (3, "Fizz"), 
        new Tuple<int, string> (5, "Buzz"), 
    };

    Func<int, int, bool> isMatch = (i, comb) => i % comb == 0;

    // expect the borders 1, 100 to come in as parameters
    for (int i = 1; i <= 100; ++i)
    {
        var matchingCombs = combinations.Where(c => isMatch(i, c.Item1)).DefaultIfEmpty(new Tuple<int, string>(i, i.ToString())).Aggregate((v, w) => new Tuple<int, string>(v.Item1, v.Item2 + w.Item2)).Item2;
        Console.WriteLine(matchingCombs);
    }
}