3

次のコードを検討してください。

    private ISet<int> CalcSumsOfTwoNums(IEnumerable<int> nums) {
        ISet<int> iset = new HashSet<int>();
        var asArray = nums.ToArray();

        for (var i = 0; i < asArray.Length - 2; i++) {
            for (var j = i; j < asArray.Length - 1; j++) {
                var sum = asArray[i] + asArray[j];
                if (sum <= MAX) {
                    iset.Add(sum);
                }
            }
        }

        return iset;
    }

forネストされたループ構文をLINQ式またはLINQドット表記に変換することは意味がありますか?forこれは、ループ構文がより適切な状況の1つですか?私の傾向はfor、結果のセットに到達するために配列を通過するときに配列のインデックス位置に依存しているため、ここではループが優れていると言うことです。

4

2 に答える 2

2
private static ISet<int> CalcSumsOfTwoNums2(IEnumerable<int> nums)
{
    // get List<int> from nums to get info about collection length
    var source = nums.ToList();

    // proper iteration
    var data = source.Take(source.Count - 1)
                     .SelectMany((e, ix) => source.Skip(ix)
                                                  .Take(source.Count - 1 - ix)
                                                  .Select(i => new { e, i }))
                     .Select(x => x.e + x.i)
                     .Where(x => x < MAX);

    // return HashSet instead of IEnumerable<int>
    return new HashSet<int>(data);
}

メソッドと同じ結果を返します。しかし、私はあなたの現在の解決策にとどまります。LINQよりもパフォーマンスが優れています。

于 2013-03-16T20:02:11.027 に答える
1

以下のLinqを試すことができます:

var asArray = nums.ToArray();
var result = (from n1 in asArray.Take(asArray.Length - 2)
              from n2 in asArray.Take(asArray.Length - 1)
              where n1 + n2 <= MAX
              select n1 + n2);

iset = new HashSet<int>(result);

スニペットと同じ出力になります。

于 2013-03-16T19:51:42.440 に答える