【问题标题】:Generating all unique combination from Dictionary<int, List<T>> [duplicate]从 Dictionary<int, List<T>> [重复] 生成所有唯一组合
【发布时间】:2017-12-28 10:06:45
【问题描述】:

我有以下字典: Dictionary&lt;int, List&lt;myObject&gt;&gt;

我想获取 myObject 的所有可能组合,并且每个键只获取一个 myObject 实例。 key 的数量和每个 key 的 myObject 数量会发生变化。

例如,如果我有以下字典:

{
  { 0, {A1, A2},
  { 1, {B1},
  { 2, {C1, C2},
}

我想要:

{A1, B1, C1}, {A1, B1, C2}, {A2, B1, C1}, {A2, B1, C2}

使用嵌套的 foreach 很容易做到这一点,如果列表的数量始终相同,但是当它发生变化时,我找不到一个简单的方法。

知道怎么做吗?

编辑: 字典不用于其他任何用途。

硬编码的嵌套 foreach 方法是(伪代码):

var result = new List<List<myObject>>
foreach myObjectA in myListForKey(0)
   foreach myObjectB in myListForKey(1)
       foreach myObjectC in myListForKey(2)
           result.add(new list<myObject>{myObjectA , myObjectB, myObjectC  })

这种方法的问题是,在这里我只能处理 3 个键的场景,它不是动态的,如果字典中有更多的键,它将不起作用或键不同。

【问题讨论】:

  • 所以,为了清楚起见,字典键不用于任何事情?

标签: c#


【解决方案1】:

假设你的三个列表都是{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}。在这种情况下,很明显可以通过取所有数字0...999 来轻松形成结果并且很明显如何为每个数字转换嵌套的foreach更好的东西:加上进位。如果为每个列表创建一个单独的枚举器并调用MoveNext() 一次以指向第一个元素,则可以很容易地概括这种“带进位相加”。现在,(enumerator[0].Current, enumerator[1].Current, ...) 包含第一个组合。要转到下一个组合,在最后一个枚举器上,再次调用MoveNext()。如果它返回true,你已经有了下一个组合。如果它没有返回true,请将其重置为再次指向第一个元素并使用倒数第二个枚举数重试。如果在某个时候MoveNext() 返回了true,那么您就有了下一个组合。如果没有返回true,你已经用尽了所有的组合。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 2023-03-21
    • 2018-11-25
    • 1970-01-01
    • 2017-05-19
    • 2015-11-30
    • 1970-01-01
    相关资源
    最近更新 更多