查找List <list <double>&gt; </list <double>的所有排列

时间:2013-02-19 13:39:15

标签: c# permutation

我遇到的情况是,我需要找到以下双打列表列表的所有排列:

List<double> A = new List<double>(){ 1, 2, 3};
List<double> B = new List<double>(){ 10, 20, 30};
List<double> C = new List<double>(){ 100, 200, 300};

需要给我:

{(1,10,100),(1,10,200),(1,10,300),(1,20,100),(1,20,200),(1,20,300)...}

我可以为固定数量的列表执行此操作,但我希望通用解决方案的灵活性(和整洁性)。我找到了处理单个列表排列的答案,但没有从每个列表中选择一个选项,如上所示。

1 个答案:

答案 0 :(得分:0)

扩展Ani的评论:我也使用Eric Lippert的解决方案来做这种事情。 (我只是将它用于单元测试所有可能的少量数据组合。)

using System;
using System.Collections.Generic;
using System.Linq;

namespace Demo
{
    public static class Program
    {
        static void Main(string[] args)
        {
            var a = new List<double> { 1, 2, 3 };
            var b = new List<double> { 10, 20, 30 };
            var c = new List<double> { 100, 200, 300 };

            var lists = new List<List<double>> {a, b, c};

            foreach (var combination in Combine(lists))
            {
                Console.WriteLine(asString(combination));
            }
        }

        static string asString(IEnumerable<double> data)
        {
            return "(" + string.Join(",", data) + ")";
        }

        /// <summary>
        /// Calculates the n-ary Cartesian Product (i.e. all possible combinations) of items taken from any
        /// number of sequences.
        /// </summary>
        /// <typeparam name="T">The type of the items in the sequences.</typeparam>
        /// <param name="sequences">The sequences to combine.</param>
        /// <returns>An enumerator that yields all possible combinations of items.</returns>
        /// <remarks>
        /// This code is taken from http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
        /// 
        /// If the sequences are ABC and 123, the output will be A1, A2, A3, B1, B2, B3, C1, C2, C3.
        /// </remarks>

        public static IEnumerable<IEnumerable<T>> Combine<T>(IEnumerable<IEnumerable<T>> sequences)
        {
            IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };

            return sequences.Aggregate(
              emptyProduct,
              (accumulator, sequence) =>
                from accseq in accumulator
                from item in sequence
                select accseq.Concat(new[] { item }));
        }
    }
}