迭代的努力--FizzBu​​zz

Jod*_*ell 0 c# string fizzbuzz c#-4.0

编辑它的价值,承认可能不是那么多.我做了一点测试来扩展这个问题.

我写了两个函数来枚举FizzBu​​zz"系列".

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));
}
Run Code Online (Sandbox Code Playgroud)

和,

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++;
    }
}
Run Code Online (Sandbox Code Playgroud)

我做了一点时间,在Release配置中编译,优化并从命令行运行.在10^8迭代过程中,没有实际报告每个项目的开销,我得到的结果接近于,

简单:14.5秒

优化:10秒

您会注意到"优化"功能更快但更冗长.它的行为可以通过改变其头部的常量来改变.


如果这看起来有点微不足道,请道歉.

考虑这个功能.

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();
}
Run Code Online (Sandbox Code Playgroud)

输出看起来像

1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
...
Run Code Online (Sandbox Code Playgroud)

有人能想出更好的方法吗?请考虑性能和可维护性.

Kon*_*lph 12

StringBuilder result = new StringBuilder();
Run Code Online (Sandbox Code Playgroud)

对于一个固定的上限(100)我不会打扰这个,但好吧......

StringBuilder line = new StringBuilder();
Run Code Online (Sandbox Code Playgroud)

但这StringBuilder不仅是多余的,而且效率非常低.我甚至不需要基准来了解这一点.

if (line.Length == 0)
Run Code Online (Sandbox Code Playgroud)

这只是模糊了逻辑(这应该实现"fizzbuzz"问题,对吧?).使逻辑明确.

请考虑性能和可维护性.

这是错误的方式.可维护性第一,性能第二(如果有的话).你的代码实际上是非常低效的,但这是无关紧要的:有100次迭代 - 性能根本不重要.

此外,此代码具有哪些可维护性开销?这是一个固定规格的玩具样品.没有可维护性问题.我甚至不想在这里有任何想法,Linq自动解决这个问题:

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()));
Run Code Online (Sandbox Code Playgroud)

但我同意,如果不习惯这个Aggregate功能,这可能会降低可读性.所以让它更明确:

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();
Run Code Online (Sandbox Code Playgroud)

其他一切都是过度工程化的.

  • @Dan ......也许吧.对于100个项目,我不会把我的钱押在`StringBuilder`上更快,我首先编写简单程序并且一旦基准测试表明它太慢就开始改进. (2认同)