1

我遇到了一种情况,我需要找到一个 List of doubles 列表的所有排列,如下所示:

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)...}

我可以为固定数量的列表做到这一点,但我想要通用解决方案的灵活性(和简洁性)。我找到了处理单个列表排列的答案,但没有从每个列表中选择一个选项,如上所示。

4

1 回答 1

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 }));
        }
    }
}
于 2013-02-19T13:56:52.413 回答