C# 写 FizzBuzz
声明:本页面是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
Writing FizzBuzz
提问by Mare Infinitus
Reading the coding horror, I just came across the FizzBuzz another time.
阅读编码恐怖,我刚刚又遇到了 FizzBuzz。
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.
对于那些不知道的人:FizzBuzz 是一款非常受欢迎的儿童游戏。从 1 数到 100,每次一个数能被 3 整除时,调用字符串“Fizz”,每次一个数能被 5 整除时,调用字符串“Buzz”,并且每次一个数都能被 3 和 5 整除将“FizzBuzz”串在一起称为“FizzBuzz”而不是数字。
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:
所以我的问题是:
- How do I get rid of the bool found?
- Is there a better way of testing than the foreach?
- 我如何摆脱发现的布尔值?
- 有没有比 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.
我认为您要完成的是 FizzBuzz 的通用解决方案,它适用于任意数量的数字-单词组合。
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用于 FizzBuzz 资格的其他一些答案略有不同。这是否更好还有待商榷。然而,这是一种不同的方式。
回答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.
FizzBuzz 问题是一个很好的面试问题。我们已经开始在面试过程中使用它。如此简单的问题,竟然有这么多人解决不了,真是令人震惊。
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);
}
}

