List<List<int>> 的有序组合
Posted
技术标签:
【中文标题】List<List<int>> 的有序组合【英文标题】:Ordered combination of List<List<int>> 【发布时间】:2012-12-21 16:41:03 【问题描述】:给定任意数量的有序列表
List<int> list1 = new List<int> 1, 1, 2;
List<int> list2 = new List<int> 1, 2, 3, 4;
List<int> list3 = new List<int> 1, 2;
List<int> listN = new List<int> ....,....;
我想找到列表的组合,以便每个组合的总和按升序找到。例如,
1, 1, 1 = 3, where 1 (1st element of list1), 1 (1st element of list2), 1 (1st element of list3)
1, 1, 1 = 3, where 1 (2nd element of list1), 1 (1st element of list2, 1 (1st element of list3)
1, 2, 1 = 4
1, 1, 2 = 4
2, 1, 1 = 4
...
按升序求和的原因是我可以选择只计算前 M 个组合(例如上面的 M = 5)。
我目前的想法是以某种方式扩展查找所有列表的组合,如 Combination of List<List<int>> 中所讨论的,从列表的一小部分开始,其中当前元素和下一个元素之间的差异为 0,例如
List<int> tempList1 = new List<int> 1, 1;
List<int> tempList2 = new List<int> 1;
List<int> tempList3 = new List<int> 1;
并找到所有组合,然后将具有最小差异的下一个元素添加到列表中
List<int> tempList1 = new List<int> 1, 1, 2;
List<int> tempList2 = new List<int> 1, 2;
List<int> tempList3 = new List<int> 1, 2;
并从那里构建解决方案集。
这可能吗,有没有更好的方法来做到这一点?
【问题讨论】:
您的意思是 summed 列表的每个组合的总和吗?即-您希望将每个列表中的所有数字相加,然后找到将所述总数相加的所有组合? 不完全。我想从每个 list1、list2、... listN 中取出一个元素并将它们相加,然后对这些总数进行排序。我将尝试在原始帖子中的示例中澄清这一点。 在您的示例中,还有两种“方法”可以获得总和4
,因为 list1
有两个相同的元素(两个 1
s),所以我认为您的问题应该反映这一点.
【参考方案1】:
计算单个项目并不昂贵,但如果项目数量很大,则将所有结果保存在内存中并对其进行排序可能会很昂贵。但是,如果我理解正确的话,计算组合似乎对解决任务没有多大帮助。
编辑:当我开始写回复时,我没有看到有关组合的说明。无论哪种方式,如果您有不同组合的生成器,也可以使用以下算法。我不确定是否有一个通用的解决方案可以只生成所需的总和。
假设 N 是项目数,M 是您想要获得的结果数。为了使以下内容有意义,我假设 N >> M(例如更大)。
然后我会使用以下算法:
创建一个最多可容纳 M 项的结果列表。 遍历所有 N 项。 对于每个项目,计算总数 在结果列表中插入总数,以便顺序正确(二进制搜索可能是一种很好的算法) 在插入后将结果列表修剪为不超过 M 项(插入的项或先前插入的项将根据它们的计算结果脱落) 您现在拥有前 M 项,按降序排列请注意,如果您愿意,您可以轻松地使上述算法相对于原始 N 项的顺序保持稳定。
【讨论】:
【参考方案2】:试试这个:
List<int> list1 = new List<int> 1, 1, 2 ;
List<int> list2 = new List<int> 1, 2, 3, 4 ;
List<int> list3 = new List<int> 1, 2 ;
var combinations = list1
.SelectMany(x => list2, (a, b) => new a, b )
.SelectMany(x => list3, (combined, c) => new a = combined.a, b = combined.b, c )
.Select(comb => new Sum = comb.a + comb.b + comb.c, Combination = new List<int>comb.a, comb.b, comb.c)
.OrderBy(summed => summed.Sum);
╔═════════════╦═════╗
║ Combination ║ Sum ║
╠═════════════╬═════╣
║ 1,1,1 ║ 3 ║
║ 1,1,1 ║ 3 ║
║ 1,1,2 ║ 4 ║
║ 1,2,1 ║ 4 ║
║ 1,1,2 ║ 4 ║
║ 1,2,1 ║ 4 ║
╚═════════════╩═════╝
编辑:清理了一下
【讨论】:
以上是关于List<List<int>> 的有序组合的主要内容,如果未能解决你的问题,请参考以下文章
将 List<int> 转换为 List<int?> 的最快方法