Linq表达式 - 仅提取最小的整数数组大小

时间:2014-05-28 21:12:15

标签: c# linq

我有一个整数列表,它只包含4个数字,如图所示,我需要写一个Linq表达式,它提取一个整数数组列表,只包含加法等于“total”的数字,听起来很简单,但这里很棘手第一部分我只想要具有最小计数的整数数组,所以如果total = 4,那么我想要int [] {4}但是我想要int [] {2,2}或int [] {1,3}等,如果总数是5那么我想要int [] {1,4},int [] {4,1},int [] {2,3},int [] {3,2},也许这可能是完成了一堆if语句,但我希望那里有一个强大的linq表达式。

var total = 5;
var numList = new List<int>() { 1, 2, 3, 4 };

2 个答案:

答案 0 :(得分:0)

您必须从一个相当复杂的代码开始,以生成源数组的所有组合。像这样:

public IEnumerable<IEnumerable<T>> Combinations<T>(IEnumerable<T> source)
{
    if (!source.Any())
    {
        return Enumerable.Empty<IEnumerable<T>>();
    }
    else if (!source.Skip(1).Any())
    {
        return new [] { source, source.Take(0) };
    }
    else
    {
        return Combinations(source.Skip(1))
            .SelectMany(xs => new [] { source.Take(1).Concat(xs), xs });
    }
}

现在剩下的很简单。就这样做:

var query =
(
    from xs in Combinations(new [] { 1, 2, 3, 4, })
    where xs.Sum() == 5
    orderby xs.Count()
    group xs by xs.Count()
)
    .Take(1)
    .SelectMany(xs => xs);

我按预期得到了以下结果:

result

答案 1 :(得分:0)

好的,这是一个函数

/// <summary>
/// Gets integer combinations between 0 and an exclusive upper bound.
/// </summary>
/// <param name="l">The length of the combination.</param>
/// <param name="n">The exclusive upper bound.</param>
/// <returns>
/// All combinations of the specified length in the specified range.
/// </returns>
public static IEnumerable<IEnumerable<int>> Combinations(int l, int n)
{
    var result = new int[l];
    var stack = new Stack<int>();
    stack.Push(0);

    while (stack.Count > 0)
    {
        var index = stack.Count - 1;
        var value = stack.Pop();

        while (value < n)
        {
            result[index++] = value++;
            stack.Push(value);
            if (index == 1)
            {
                yield return result;
                break;
            }
        }
    }
}

你可以在这样的扩展方法中使用它。

public static IEnumerable<IEnumerable<T>> CombinationsIncreasingLength<T>(
        this IEnumerable<T> source)
{
    var sourceList = source.ToList();

    if (sourceList.Count < 2)
    {
        return new[] { sourceList };
    }

    return
        Enumerable.Range(1, sourceList.Count)
            .SelectMany(l => Combinations(l, sourceList.Count)
                .Select(indices => indices.Select(i => sourceList[i])));
}

这将为您提供source 增加长度的所有组合

因此,要找到与值完全相加的最短组合,您可以这样做。

numList.CombinationsIncreasingLength().First(c => c.Sum() == total);