努力迭代 - FizzBu​​zz [英] Efforts in iteration - FizzBuzz

查看:124
本文介绍了努力迭代 - FizzBu​​zz的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

修改为了什么它的价值,这admittedley可能没有那么多。我做了一个小测试,以扩大这一问题。



我已经写了两个函数来枚举FizzBu​​zz系列。

 私有静态的IEnumerable<串GT; SimpleFizzBu​​zz(
INT开始= 0,
INT结束= int.MaxValue)
{
返回Enumerable.Range(开始,结束)。选择(I =>
I%15 == 0fizzbuzz:
I%3 == 0嘶嘶:
I%5 == 0嗡嗡:
i.ToString(CultureInfo.InvariantCulture ));
}

 私有静态的IEnumerable<串GT; OptimizedFizzBu​​zz(
INT开始= 0,
INT结束= int.MaxValue)
{
const int的嘶嘶声= 3;
const int的嗡嗡声= 5;
常量字符串fizzString =香味;
常量字符串buzzString =嗡嗡;
常量字符串fizzBu​​zzString = fizzString + buzzString;

VAR fizzer =启动香味%;
VAR蜂鸣器=开始嗡嗡%;

如果(fizzer == 0)
{
fizzer =香味;
}

如果(蜂鸣器== 0)
{
蜂鸣器=嗡嗡声;
}

为(VAR I =启动; I< =结束;我++)
{
如果(蜂鸣器==嗡嗡声)
{
如果(fizzer ==嘶嘶声)
{
收益率的回报fizzBu​​zzString;
蜂鸣器= 1;
fizzer = 1;
继续;
}

收益率的回报buzzString;
蜂鸣器= 1;
fizzer ++;
继续;
}

如果(fizzer ==嘶嘶声)
{
收益率的回报fizzString;
蜂鸣器++;
fizzer = 1;
继续;
}

收益率的回报i.ToString(CultureInfo.InvariantCulture);
fizzer ++;
蜂鸣器++;
}
}



我已经做了一些时间,在编译版配置,通过命令行的优化和运行。在 10 ^ 8 迭代,没有实际报告的每一项开销,我得到的结果接近,




简单:14.5秒。



优化:10秒




您会注意到,优化的功能,速度更快,但是更详细。它的行为可以通过简单地在其头部改变常数被改变。






道歉,如果这似乎有点微不足道。

考虑这个功能。

 使用System.Text; 

公共字符串FizzBanger(INT结合)
{
StringBuilder的结果=新的StringBuilder();
的for(int i = 1; I<约束;我++)
{
串线=的String.Empty;
如果(I%3 == 0)行+ =香味;
如果(I%5 == 0)行+ =嗡嗡;
如果(String.IsNullOrEmpty(线))行= i.ToString();
result.AppendLine(line.ToString());
}
返回result.ToString();
}

输出看起来像

  1 
2
香味
4
嗡嗡
香味
7
$ 8 b $ b香味
嗡嗡
11
香味
13
14
fizzbuzz
16
...

任何人能想到这样做的更好的办法?请同时考虑性能和可维护性。


解决方案

 的StringBuilder结果=新的StringBuilder(); 




对于一个固定的上限(100)我不会理会与此,但确定...




 的StringBuilder行=新的StringBuilder(); 




但这个的StringBuilder 不仅是多余的,它真的很低效。而且我也不需要基准知道这一点。




 如果(line.Length = = 0)




这只是模糊逻辑(这是应该为贯彻落实fizzbuzz的问题,对吧?)。使逻辑清晰。




请同时考虑性能和可维护性。




这是错误的方式轮。可维护性第一,第二的性能(如果有的话)。您的代码实际上是相当低效的,但是这无关紧要:有100次迭代 - 业绩并不在所有问题



此外,这段代码有什么维护的开销?它与固定规格的玩具样品。没有可维护性的问题。我甚至不会有任何幻想在这里打扰,LINQ的解决了这个自动的:

 返回Enumerable.Range(1,势必 -  1 ).Aggregate(,
(ACCU,I)=>
的String.Format({0} \\\
{1},ACCU,
I%15 == 0 ?fizzbuzz:
I%3 == 0嘶嘶:
I%5 == 0嗡嗡:?i.ToString()));



不过,我认为,如果一个人不习惯总结功能。因此,使它更加明确:

  VAR的结果=新的StringBuilder(); 
的for(int i = 1; I<约束;我++)
result.AppendLine(
I%15 == 0fizzbuzz:
I%3 == 0? 嘶:
I%5 == 0嗡嗡:i.ToString());?
返回result.ToString();



一切是过度工程。


EDIT For what its worth, which admittedley may not be that much. I've done a little test to expand this question.

I've written two functions to enumerate the FizzBuzz "series."

private static IEnumerable<string> SimpleFizzBuzz(
        int start = 0,
        int end = int.MaxValue)
{
    return Enumerable.Range(start, end).Select(i =>
        i % 15 == 0 ? "fizzbuzz" :
        i % 3 == 0 ? "fizz" :
        i % 5 == 0 ? "buzz" :
        i.ToString(CultureInfo.InvariantCulture));
}

and,

private static IEnumerable<string> OptimizedFizzBuzz(
        int start = 0,
        int end = int.MaxValue)
{
    const int fizz = 3;
    const int buzz = 5;
    const string fizzString = "fizz";
    const string buzzString = "buzz";
    const string fizzBuzzString = fizzString + buzzString;

    var fizzer = start % fizz;
    var buzzer = start % buzz;

    if (fizzer == 0)
    {
        fizzer = fizz;
    }

    if (buzzer == 0)
    {
        buzzer = buzz;
    }

    for (var i = start; i <= end; i++)
    {
        if (buzzer == buzz)
        {
            if (fizzer == fizz)
            {
                yield return fizzBuzzString;
                buzzer = 1;
                fizzer = 1;
                continue;
            }

            yield return buzzString;
            buzzer = 1;
            fizzer++;
            continue;
        }

        if (fizzer == fizz)
        {
            yield return fizzString;
            buzzer++;
            fizzer = 1;
            continue;
        }

        yield return i.ToString(CultureInfo.InvariantCulture);
        fizzer++;
        buzzer++;
    }
}

I've done a little timing, compiled in Release configuration, with optimizations and run from the command line. Over 10^8 iterations, without the overhead of actually reporting each item, I get results that approximate to,

Simple: 14.5 Seconds

Optimized: 10 Seconds

You'll note that the "optimized" function is faster but more verbose. It's behaviour can be altered simply by changing the constants at its head.


Apologies if this seems a little trivial.

Consider this function.

using System.Text;

public string FizzBanger(int bound)
{
    StringBuilder result = new StringBuilder();
    for (int i = 1; i < bound; i++)
    {
        String line = String.Empty;
        if (i % 3 == 0) line += "fizz";
        if (i % 5 == 0) line += "buzz";
        if (String.IsNullOrEmpty(line)) line = i.ToString();
        result.AppendLine(line.ToString());
    }
    return result.ToString();
}

The output will look like

1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
...

Can anybody think of a better way of doing it? Please consider both performance and maintainability.

解决方案

StringBuilder result = new StringBuilder();

For a fixed upper bound (100) I wouldn’t bother with this but ok …

StringBuilder line = new StringBuilder();

But this StringBuilder isn’t only redundant, it’s really inefficient. And I don’t even need to benchmark to know this.

if (line.Length == 0)

And this just obscures the logic (this is supposed to implement the "fizzbuzz" problem, right?). Make the logic explicit.

Please consider both performance and maintainability.

That’s the wrong way round. Maintainability first, performance second (if at all). Your code is actually quite inefficient but that’s irrelevant: there are 100 iterations – performance doesn’t matter at all.

Furthermore, what maintainability overhead does this code have? It’s a toy sample with fixed specs. There are no maintainability issues. I wouldn’t even bother with anything fancy here, Linq solves this automagically:

return Enumerable.Range(1, bound - 1).Aggregate("",
    (accu, i) =>
        string.Format("{0}\n{1}", accu,
            i % 15 == 0 ? "fizzbuzz" :
            i % 3 == 0 ? "fizz" :
            i % 5 == 0 ? "buzz" : i.ToString()));

But I agree that this may strain readability if one isn’t used to the Aggregate function. So make it more explicit:

var result = new StringBuilder();
for (int i = 1; i < bound; i++)
    result.AppendLine(
        i % 15 == 0 ? "fizzbuzz" :
        i % 3 == 0 ? "fizz" :
        i % 5 == 0 ? "buzz" : i.ToString());
return result.ToString();

Everything else is over-engineering.

这篇关于努力迭代 - FizzBu​​zz的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆