我正在上课,找到N个列表的每个组合。组合算法似乎完美无缺(当我单步执行时),但我无法保存结果。我想将所有生成的数组存储在另一个列表中以供稍后使用,但是当我执行最后一个数组时会覆盖所有以前的数组。示例输入/输出和我的代码如下。有没有人有任何想法如何解决这个问题? (我已尝试过具有相同结果的参考参数和全局列表。)
/*
Input: A B C
X Y
Expected Output: A X
A Y
B X
B Y
C X
C Y
Actual Output: C Y
C Y
C Y
C Y
C Y
C Y
*/
public class Combination<T>{
private static void Combine(T[] res, int ix, List<List<T>> data, ref List<T[]> allCombos){
foreach (T v in data[ix]){
res[ix] = v;
if (ix >= data.Count - 1){
allCombos.Add(res);
}else{
Combine(res, ix + 1, data, ref allCombos);
}
}
}
public static List<T[]> Combine(List<List<T>> data){
List<T[]> allCombos = new List<T[]>();
Combine(new T[data.Count], 0, data, ref allCombos);
return allCombos;
}
}
答案 0 :(得分:2)
这里的主要问题是您只分配一个T[]
实例。您只是一遍又一遍地添加到List<T[]>
。
而不是:
allCombos.Add(res);
你应该试试这个:
allCombos.Add(res.ToArray());
每次将数组添加到列表中时,都会创建一个新的数组副本。
答案 1 :(得分:0)
试试这个。我认为这应该有效。我不是在终端上测试它。
public class Combination<T>
{
static T[] res;
private static void Combine(int ix, List<List<T>> data, ref List<T[]> allCombos)
{
foreach (T v in data[ix])
{
res[ix] = v;
if (ix >= data.Count - 1)
{
allCombos.Add(res);
}
else
{
Combine(res, ix + 1, data, ref allCombos);
}
}
}
public static List<T[]> Combine(List<List<T>> data)
{
List<T[]> allCombos = new List<T[]>();
res = new T[data.Count];
Combine(0, data, ref allCombos);
return allCombos;
}
}
答案 2 :(得分:0)
问题是res参数在每次迭代中被重用和覆盖。这是我的解决方案。
using System;
using System.Linq;
using System.Collections.Generic;
....
private IEnumerable<T[]> Combine<T>(IEnumerable<T[]> data)
{
if (!data.Any())
yield break;
var head = data.First();
var tail = Combine(data.Skip(1));
foreach (var e in head)
{
var list = new T[] {e};
if (!tail.Any())
yield return list;
else
{
foreach (var t in tail)
{
yield return list.Concat(t).ToArray();
}
}
}
}
答案 3 :(得分:0)
记录下来,我遇到了类似的问题,最近发布了一系列自定义对象。对我来说,基本上是创建一个新对象,并使用原来用于覆盖的对象(“ subTree”)作为基础。
//Do this
TreeView newTree= new TreeView {
name = subTree.name,
children = subTree.children
};
actualTree.Add(newTree);
//Not this
actualTree.Add(subTree)
如果我不这样做,每次尝试将TreeView元素添加到“ actualTree”列表中时,我都会得到最后一个“ subTree”对象。解决方案是,每当必须向列表中添加元素时,就使用其他对象所需的值创建一个新对象,这样就不必总是添加同一对象。