埃里克利珀的挑战和QUOT;逗号纠缠&QUOT ;,最好的答案? [英] Eric Lippert's challenge "comma-quibbling", best answer?

查看:156
本文介绍了埃里克利珀的挑战和QUOT;逗号纠缠&QUOT ;,最好的答案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望把这个挑战,计算器社会的关注。原来的问题,答案是这里。顺便说一句,如果你没有按照之前,你应该尝试阅读Eric的博客,它是纯粹的智慧。

摘要:

编写一个函数,它接受一个非空IEnumerable和返回一个字符串,具有以下特点:


  1. 如果序列为空,结果字符串为{}。

  2. 如果该序列是单个项目的ABC,那么结果字符串为{} ABC。

  3. 如果该序列是两个项目序列ABC,DEF,那么结果字符串为{ABC和DEF}。

  4. 如果顺序有两个以上的项目,比如,ABC,DEF,G,H,那么结果字符串为{ABC,DEF,G和H}。 (注:无牛津逗号)

如你所见,甚至我们自己的乔恩斯基特(​​是的,这是众所周知的他可以有两种同时地方)发布了一个解决方案,但尽管可能你不能打败它的性能对他(恕我直言)是不是最优雅的。

你觉得呢?有pretty不错的选择那里。我真的很喜欢,涉及到选择和聚合方法(从费尔南多·尼高)的解决方案之一。 LINQ是非常强大和奉献一些时间来这样能让你学到很多挑战。我扭有点所以它是多一点高性能和清晰的(通过使用计数和避免反向):

 公共静态字符串CommaQuibbling(IEnumerable的<串GT;项目)
{
    INT最后= items.Count() - 1;
    FUNC< INT,串> getSeparator =(ⅰ)=>我== 0?的String.Empty:(ⅰ==持续和:,);
    串答案=的String.Empty;    返回{+ items.Select((S,I)=>新建{指数=我,值= S})
                      .Aggregate(回答,(S,A)=> S + getSeparator(a.Index)+ a.value中)+};
}


解决方案

这个怎么样的做法?纯粹的累积 - 无背跟踪,只有一次迭代。对于原始的表现,我不知道你会做的更好使用LINQ等等,无论怎么pretty一个LINQ的答案可能是。

 使用系统;
使用System.Collections.Generic;
使用System.Text;静态类节目
{
    公共静态字符串CommaQuibbling(IEnumerable的<串GT;项目)
    {
        StringBuilder的SB =新的StringBuilder('{');
        使用(VAR ITER = items.GetEnumerator())
        {
            如果(iter.MoveNext())
            {//第一个项目,可直接追加
                sb.Append(iter.Current);
                如果(iter.MoveNext())
                { // 超过一个;只有每添加
                  //长期当我们知道有另一个
                    字符串lastItem = iter.Current;
                    而(iter.MoveNext())
                    {//中期;使用 ,
                        sb.Append(,).Append(lastItem);
                        lastItem = iter.Current;
                    }
                    //添加最后期限;由于我们是在至少
                    //第二个任期内,总是用和
                    sb.Append(和).Append(lastItem);
                }
            }
        }
        返回sb.Append(})的ToString()。
    }
    静态无效的主要()
    {
        Console.WriteLine(CommaQuibbling(新的String [] {}));
        Console.WriteLine(CommaQuibbling(新的String [] {ABC}));
        Console.WriteLine(CommaQuibbling(新的String [] {ABC,DEF}));
        Console.WriteLine(CommaQuibbling(新的String [] {
             ABC,DEF,G,H}));
    }
}

I wanted to bring this challenge to the attention of the stackoverflow community. The original problem and answers are here. BTW, if you did not follow it before, you should try to read Eric's blog, it is pure wisdom.

Summary:

Write a function that takes a non-null IEnumerable and returns a string with the following characteristics:

  1. If the sequence is empty the resulting string is "{}".
  2. If the sequence is a single item "ABC" then the resulting string is "{ABC}".
  3. If the sequence is the two item sequence "ABC", "DEF" then the resulting string is "{ABC and DEF}".
  4. If the sequence has more than two items, say, "ABC", "DEF", "G", "H" then the resulting string is "{ABC, DEF, G and H}". (Note: no Oxford comma!)

As you can see even our very own Jon Skeet (yes, it is well known that he can be in two places at the same time) has posted a solution but his (IMHO) is not the most elegant although probably you can not beat its performance.

What do you think? There are pretty good options there. I really like one of the solutions that involves the select and aggregate methods (from Fernando Nicolet). Linq is very powerful and dedicating some time to challenges like this make you learn a lot. I twisted it a bit so it is a bit more performant and clear (by using Count and avoiding Reverse):

public static string CommaQuibbling(IEnumerable<string> items)
{
    int last = items.Count() - 1;
    Func<int, string> getSeparator = (i) => i == 0 ? string.Empty : (i == last ? " and " : ", ");
    string answer = string.Empty;

    return "{" + items.Select((s, i) => new { Index = i, Value = s })
                      .Aggregate(answer, (s, a) => s + getSeparator(a.Index) + a.Value) + "}";
}

解决方案

How about this approach? Purely cumulative - no back-tracking, and only iterates once. For raw performance, I'm not sure you'll do better with LINQ etc, regardless of how "pretty" a LINQ answer might be.

using System;
using System.Collections.Generic;
using System.Text;

static class Program
{
    public static string CommaQuibbling(IEnumerable<string> items)
    {
        StringBuilder sb = new StringBuilder('{');
        using (var iter = items.GetEnumerator())
        {
            if (iter.MoveNext())
            { // first item can be appended directly
                sb.Append(iter.Current);
                if (iter.MoveNext())
                { // more than one; only add each
                  // term when we know there is another
                    string lastItem = iter.Current;
                    while (iter.MoveNext())
                    { // middle term; use ", "
                        sb.Append(", ").Append(lastItem);
                        lastItem = iter.Current;
                    }
                    // add the final term; since we are on at least the
                    // second term, always use " and "
                    sb.Append(" and ").Append(lastItem);
                }
            }
        }
        return sb.Append('}').ToString();
    }
    static void Main()
    {
        Console.WriteLine(CommaQuibbling(new string[] { }));
        Console.WriteLine(CommaQuibbling(new string[] { "ABC" }));
        Console.WriteLine(CommaQuibbling(new string[] { "ABC", "DEF" }));
        Console.WriteLine(CommaQuibbling(new string[] {
             "ABC", "DEF", "G", "H" }));
    }
}

这篇关于埃里克利珀的挑战和QUOT;逗号纠缠&QUOT ;,最好的答案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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