c# – 获取k元素的所有组合并重复

我希望获得所有可能组合的列表并重复.

例如

Input: 1,2,3 
Result: 111,112,...,332,333

为此我使用this改进的方法,这是正常的

public static IEnumerable<IEnumerable<T>> CombinationsWithRepeat<T>(this IEnumerable<T> elements, int k)
{
    return k == 0 ? new[] { new T[0] } : elements.SelectMany((e, i) => elements.CombinationsWithRepeat(k - 1).Select(c => (new[] { e }).Concat(c)));
}

我的问题是这种递归方法的内存使用情况.输入60个元素且K = 4时,已经存在Out of Memory Exception.

我需要以K = 10运行它.

问题:有一种简单的方法可以避免这种异常吗?我需要一种迭代方法吗?

更新:

提到Corak的评论 –
K必须是动态的

这应该适用于60个元素和K = 10,但它不是动态的.

StreamWriter sr = new StreamWriter(@"c:\temp.dat");
List<char> cList = new List<char>() { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
for (int i = 0; i < cList.Count; i++)
    for (int j = 0; j < cList.Count; j++)
        for (int k = 0; k < cList.Count; k++)
            sr.WriteLine(cList[i] + cList[j] + cList[k]);

最佳答案 你的功能没有问题.如果您不尝试将生成的IEnumerable放入内存中(例如调用ToArray()),则不会出现Out Of Memory Exception.

下面的例子很好用.

class Program
{
    static void Main(string[] args)
    {
        var input = Enumerable.Range(1, 60);

        using (var textWriter = File.AppendText("result.txt"))
        {
            foreach (var combination in input.CombinationsWithRepeat(10))
            {
                foreach (var digit in combination)
                {
                    textWriter.Write(digit);
                }
                textWriter.WriteLine();
            }
        }
    }
}

public static class Extensions
{
    public static IEnumerable<IEnumerable<T>> CombinationsWithRepeat<T>(this IEnumerable<T> elements, int k)
    {
        return k == 0 ? new[] { new T[0] } : elements.SelectMany((e, i) => elements.CombinationsWithRepeat(k - 1).Select(c => (new[] { e }).Concat(c)));
    }
}

但即使在硬盘上你也没有足够的空间来存储结果.有60 ^ 10种组合.每种组合使用10-20个字节.

您想如何使用您的功能结果?

点赞