algorithm - 生成从大量列表中选择一个元素的所有组合

时间:2015-12-22 23:35:06

标签: c# algorithm combinatorics

让我们说我有三个清单:

A = {“b”,“c”,“d”,“x”,“y”,“z”}

B = {“a”,“e”,“i”}

我想生成从两个列表中选择一个元素的所有组合。

对于2个列表,这很容易(pseuodo-ish代码):

combinations = []
for a in A:
    for b in B:
        combinations += [a, b]

但是,如果列表的数量未知,该怎么办? 我想用C#扩展方法以某种方式推广这个。

方法签名将是这样的:

public static IEnumerable<IEnumerable<T>> Combination<T>(this IEnumerable<IEnumerable<T>> elements)

修改 我正在寻找笛卡尔积,感谢您的澄清。

2 个答案:

答案 0 :(得分:1)

如果你只是平面组合,并且你有一组这些套装,你应该能够在套装上使用SelectMany。

public static IEnumerable<[T]> Combination<T>(this IEnumerable<IEnumerable<T>> elements)
{
    return elements.Select( 
        e => elements.Except(e).SelectMany( t => new T[e,t] )
    );
}

答案 1 :(得分:0)

假设您希望所有组合包括具有不同顺序的重复元素的组合,这基本上是现有方法SelectMany所做的。

使用查询表达式和匿名对象获取所有组合相当容易。这是一个例子:

var combinations = from a in allAs
                   from b in allBs
                   select new { A = a, B = b };

一举这样做(使用建议的Combination方法)至少需要你:

  • 提供“选择”组合的功能(类似于Zip方法的签名)
  • 或者,返回通用Tuple<T, T>

但话又说回来,它实际上只是取代了笛卡尔积(SelectMany)和投影(Select)的用法,两者都已经存在。