假设我有以下三个列表
A1
A2
A3
B1
B2
C1
C2
C3
C4
C5
我想将它们组合成一个列表,每个列表中的项目尽可能均匀分布,如下所示:
C1
A1
C2
B1
C3
A2
C4
B2
A3
C5
我正在使用.NET 3.5 / C#,但我正在寻找更多关于如何处理特定代码的信息。
编辑:我需要保留原始列表中元素的顺序。
答案 0 :(得分:17)
获取成员最多的列表副本。这将是目的地列表。
然后选择下一个最大数字的列表。
将目的地列表长度除以较小的长度,以得到大于1的小数值。
对于第二个列表中的每个项目,维护一个浮点计数器。添加上一步中计算的值,并在数学上将其四舍五入为最接近的整数(保持原始浮点计数器完好无损)。将其插入目的地列表中的此位置,并将计数器增加1以说明它。对第二个列表中的所有列表成员重复。
对所有列表重复步骤2-5。
编辑:这也有O(n)的优点,这总是很好:)
答案 1 :(得分:2)
首先,这个答案更多的是一种思路而不是一种解决方案。
好的,所以你有一个包含3个项目(A1,A2,A3)的列表,你希望A1在目标列表的前1/3中的某个位置,在目标列表的第二个1/3中的A2和1/3中的A3。同样,你希望B1在第一个1/2等等......
因此,您将10列表作为数组分配,然后从包含最多项目的列表开始,在本例中为C.计算C1应落下的位置(1.5)在最近的位置放置C1,(在这种情况下) ,1或2),然后计算C2应该下降的位置(3.5)并继续该过程,直到没有更多的Cs。
然后使用第二个到最多数量的项目列表。在这种情况下,A。计算A1的位置(1.66),所以先尝试2。如果您已将C1放在那里,请尝试1.对A2(4.66)和A3(7.66)执行相同操作。最后,我们列出B.B1应该是2.5,所以尝试2或3.如果两者都采取,尝试1和4并继续径向移动,直到找到一个空位。为B2做同样的事。
如果你选择较低的数字,你最终会得到类似的东西:
C1 A1 C2 A2 C3 B1 C4 A3 C5 B2
或者如果您选择上面的数字:
A1 C1 B1 C2 A2 C3 A3 C4 B2 C5
这似乎对您的示例列表非常有效,但我不知道它可以扩展到包含许多项目的许多列表。试一试,让我知道它是怎么回事。
答案 2 :(得分:2)
实施 Andrew Rollings的回答:
public List<String> equimix(List<List<String>> input) {
// sort biggest list to smallest list
Collections.sort(input, new Comparator<List<String>>() {
public int compare(List<String> a1, List<String> a2) {
return a2.size() - a1.size();
}
});
List<String> output = input.get(0);
for (int i = 1; i < input.size(); i++) {
output = equimix(output, input.get(i));
}
return output;
}
public List<String> equimix(List<String> listA, List<String> listB) {
if (listB.size() > listA.size()) {
List<String> temp;
temp = listB;
listB = listA;
listA = temp;
}
List<String> output = listA;
double shiftCoeff = (double) listA.size() / listB.size();
double floatCounter = shiftCoeff;
for (String item : listB) {
int insertionIndex = (int) Math.round(floatCounter);
output.add(insertionIndex, item);
floatCounter += (1+shiftCoeff);
}
return output;
}
答案 3 :(得分:1)
我正在考虑分而治之的方法。每次迭代,您将所有列表拆分为元素&gt; 1比一并递减。当你到达一个点,除了一个列表之外的所有列表都是一个元素你可以随机组合它们,弹出一个级别并随机组合从那个长度为1的帧中删除的列表......等等。
以下是我的想法:
- filter lists into three categories
- lists of length 1
- first half of the elements of lists with > 1 elements
- second half of the elements of lists with > 1 elements
- recurse on the first and second half of the lists if they have > 1 element
- combine results of above computation in order
- randomly combine the list of singletons into returned list
答案 4 :(得分:1)
(/ n (+ (length list) 1))
答案 5 :(得分:0)
您可以简单地将三个列表合并到一个列表中,然后排列UNSORT。未排序的列表应该不需要太多努力就可以达到“均匀分布”的要求。
这是unsort的实现:http://www.vanheusden.com/unsort/。
答案 6 :(得分:-1)
快速建议,用python-ish伪代码:
merge = list()
lists = list(list_a, list_b, list_c)
lists.sort_by(length, descending)
while lists is not empty:
l = lists.remove_first()
merge.append(l.remove_first())
if l is not empty:
next = lists.remove_first()
lists.append(l)
lists.sort_by(length, descending)
lists.prepend(next)
这应该比其他建议更均匀地分配较短列表中的元素。