7

インタビューで以下の.NETの質問がありました。なぜ低得点になったのかわかりません。残念ながら、フィードバックはありませんでした。

質問:

ファイルhockey.csvには、ホッケープレミアリーグの結果が含まれています。「For」と「Against」の列には、そのシーズンに各チームに対して得点されたゴールの総数が含まれます(したがって、アラバマは対戦相手に対して79ゴールを獲得し、36ゴールを獲得しました)。

「for」と「against」の目標の差が最も小さいチームの名前を印刷するプログラムを作成します。

hockey.csvの構造は次のようになります(これは有効なcsvファイルですが、アイデアを得るためにここに値をコピーしただけです)

チーム-のために-に対して

アラバマ7936

ワシントン6730

インディアナ8745

ニューカッスル7452

フロリダ5337

ニューヨーク4647

サンダーランド2951

Lova 41 64

ネバダ3363

ボストン3064

ネバダ3363

ボストン3064

解決:

class Program
{
    static void Main(string[] args)
    {
        string path = @"C:\Users\<valid csv path>";

        var resultEvaluator = new ResultEvaluator(string.Format(@"{0}\{1}",path, "hockey.csv"));
        var team = resultEvaluator.GetTeamSmallestDifferenceForAgainst();

        Console.WriteLine(
            string.Format("Smallest difference in ‘For’ and ‘Against’ goals > TEAM: {0}, GOALS DIF: {1}",
            team.Name, team.Difference ));

        Console.ReadLine();
    }
}

public interface IResultEvaluator
{
    Team GetTeamSmallestDifferenceForAgainst();
}

public class ResultEvaluator : IResultEvaluator
{
    private static DataTable leagueDataTable;
    private readonly string filePath;
    private readonly ICsvExtractor csvExtractor;

    public ResultEvaluator(string filePath){
        this.filePath = filePath;
        csvExtractor = new CsvExtractor();
    }

    private DataTable LeagueDataTable{
        get
        {
            if (leagueDataTable == null)
            {
                leagueDataTable = csvExtractor.GetDataTable(filePath);
            }

            return leagueDataTable;
        }
    }

    public Team GetTeamSmallestDifferenceForAgainst() {
        var teams = GetTeams();
        var lowestTeam = teams.OrderBy(p => p.Difference).First();
        return lowestTeam;
    }

    private IEnumerable<Team> GetTeams() {
        IList<Team> list = new List<Team>();

        foreach (DataRow row in LeagueDataTable.Rows)
        {
            var name = row["Team"].ToString();
            var @for = int.Parse(row["For"].ToString());
            var against = int.Parse(row["Against"].ToString());
            var team = new Team(name, against, @for);
            list.Add(team);
        }

        return list;
    }
}

public interface ICsvExtractor
{
    DataTable GetDataTable(string csvFilePath);
}

public class CsvExtractor : ICsvExtractor
{
    public DataTable GetDataTable(string csvFilePath)
    {
        var lines = File.ReadAllLines(csvFilePath);

        string[] fields;

        fields = lines[0].Split(new[] { ',' });
        int columns = fields.GetLength(0);
        var dt = new DataTable();

        //always assume 1st row is the column name.
        for (int i = 0; i < columns; i++)
        {
            dt.Columns.Add(fields[i].ToLower(), typeof(string));
        }

        DataRow row;
        for (int i = 1; i < lines.GetLength(0); i++)
        {
            fields = lines[i].Split(new char[] { ',' });

            row = dt.NewRow();
            for (int f = 0; f < columns; f++)
                row[f] = fields[f];
            dt.Rows.Add(row);
        }

        return dt;
    }
}

public class Team
{
    public Team(string name, int against, int @for)
    {
        Name = name;
        Against = against;
        For = @for;
    }

    public string Name { get; private set; }

    public int Against { get; private set; }

    public int For { get; private set; }

    public int Difference
    {
        get { return (For - Against); }
    }
}

出力:目標に対する最小for' andの差>チーム:ボストン、ゴールDIF:-34

誰かが私のコードを確認して、ここで明らかに間違っていることを確認できますか?彼らは、コードの構造/設計と、プログラムが正しい結果(つまり、最小の差)を生成するかどうかにのみ関心がありました。とても有難い。

4

3 に答える 3

11

たぶん、あなたが非常に多くのコード行を書いたからでしょう。

var teamRecords = File.ReadAllLines("path");
var currentLow = int.MaxValue;
foreach (var record in teamRecords.Skip(1).ToList())
{
    var tokens = record.Split(',');
    if (tokens.Length == 3)
    {
        int forValue = 0;
        int againstValue = 0;

        if (int.TryParse(tokens[1], out forValue) && int.TryParse(tokens[2], out againstValue))
        {
            var difference = Math.Abs(forValue - againstValue);
            if (difference < currentLow) currentLow = difference;
        }
     }
 }

 Console.WriteLine(currentLow);
于 2012-06-22T03:24:59.770 に答える
6

私はあなたが質問を理解し損ねていると思います。インタビュアーは、「for」と「against」の目標の最小差を尋ねました。あなたのプログラムは、最良の目標平均を計算しています。最小の違いが見られる場合は、ボストンではなくニューヨークです。ここでfenix2222コードを更新しましょう。

var teamRecords = File.ReadAllLines(Path.Combine(Application.StartupPath,"teams.csv"));
            var currentLow = int.MaxValue; //just to make sure that difference is initially less than currentLow.
            foreach (var record in teamRecords.Skip(1).ToList())
            {
                var tokens = record.Split(',');
                if (tokens.Length == 3)
                {
                    int forValue = 0;
                    int againstValue = 0;

                    if (int.TryParse(tokens[1], out forValue) && int.TryParse(tokens[2], out againstValue))
                    {
                        var difference = 0;
                        if (forValue > againstValue)
                            difference = forValue - againstValue;
                        else
                            difference = againstValue - forValue;

                        if (difference < currentLow) 
                            currentLow = difference;
                    }
                }
            }
于 2012-06-22T04:46:10.713 に答える
3

大まかな概要からのほんのいくつかのこと:

  1. 2つのインターフェースがありますが、どちらの用途にも価値はありません。
  2. 問題ステートメントにDataTableを導入する理由はありません。
  3. コードは非常に複雑です。
  4. GetTeamsメソッドでのIListとIEnumerableの使用は、「理由だけで」使用されているように見えます。
  5. ResultEvaluatorクラスは再利用できません。つまり、クラスをインスタンス化するとすぐに、csvファイルを再設定することはできません。同じメソッド(GetTeamSmallestDifferenceForAgainst)を何度も呼び出し続けることしかできません。他の公共施設は利用できません。
  6. GetDataTableメソッドでは、string []フィールドが1行で宣言され、値が次の行で設定されます。
  7. Teamクラスのコンストラクターの「for」パラメーターに@記号を使用する理由はゼロ未満です。予約語の名前を「for」に変更するだけです。
  8. 問題をはるかに簡単に解決するために使用できる3.5以降の.NETからの多くの構成があります。これは、言語の理解の欠如を示しています。

見た目からすると、問題の説明で求められていることよりもかなり多くのことを知っていることを示しようとしていたようです。しかし、あなたが知っている知識がこの演習でどのように使用されているかは非常に恐ろしく、良い方法ではありません。

将来的には、目前の問題を解決するだけで、考えすぎないことをお勧めします。単純にする。

于 2012-06-22T04:57:57.480 に答える