Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 将N个列表中的项目合并为一个均衡分布的项目的好算法?_Algorithm_List - Fatal编程技术网

Algorithm 将N个列表中的项目合并为一个均衡分布的项目的好算法?

Algorithm 将N个列表中的项目合并为一个均衡分布的项目的好算法?,algorithm,list,Algorithm,List,假设我有以下三个列表 A1 A2 A3 B1 B2 C1 C2 C3 C4 碳五 我想将它们合并成一个列表,每个列表中的项目尽可能均匀分布,如下图所示: C1 A1 C2 B1 C3 A2 C4 B2 A3 碳五 我使用的是.NET3.5/C,但我更关注的是如何使用特定代码 编辑:我需要保持原始列表中元素的顺序。您可以简单地将三个列表合并为一个列表,然后取消对该列表的排序。一份未排序的列表应该可以实现您的“均匀分布”要求,而无需付出太多努力 这是unsort的一个实现:。我正在考虑一种分而治之的

假设我有以下三个列表

A1
A2
A3

B1
B2

C1
C2
C3
C4
碳五

我想将它们合并成一个列表,每个列表中的项目尽可能均匀分布,如下图所示:

C1
A1
C2
B1
C3
A2
C4
B2
A3
碳五

我使用的是.NET3.5/C,但我更关注的是如何使用特定代码


编辑:我需要保持原始列表中元素的顺序。

您可以简单地将三个列表合并为一个列表,然后取消对该列表的排序。一份未排序的列表应该可以实现您的“均匀分布”要求,而无需付出太多努力


这是unsort的一个实现:。

我正在考虑一种分而治之的方法。您将所有元素大于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 

python伪代码中的一个快速建议:

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)
这将比此处的其他建议更均匀地分布较短列表中的元素

  • 复制一份成员最多的列表。这将是目的地列表

  • 然后选择下一个拥有最多成员的列表

  • 将目标列表长度除以较小的长度,得到大于1的分数值

  • 对于第二个列表中的每个项目,维护一个浮动计数器。将上一步计算的值相加,并从数学上将其四舍五入到最接近的整数(保持原始浮点计数器不变)。将其插入目标列表中的此位置,并将计数器增加1以说明其原因。对第二个列表中的所有列表成员重复此操作

  • 对所有列表重复步骤2-5


  • 编辑:这也有O(n)的优点,这总是好的:)

    首先,这个答案更像是一个思路,而不是一个复杂的解决方案

    好的,你有一个3个项目的列表(A1,A2,A3),你希望A1在目标列表的前1/3,A2在目标列表的第二个1/3,A3在第三个1/3。同样,您希望B1位于前1/2,以此类推

    因此,您将10个列表分配为一个数组,然后从项目最多的列表开始,在本例中为C。计算C1应落下的位置(1.5)将C1落在最近的位置(在本例中为1或2),然后计算C2应落下的位置(3.5),并继续此过程,直到没有更多的C

    然后按照第二至最多项目的列表进行操作。在本例中,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

    这似乎对您的示例列表非常有效,但我不知道它在多大程度上可以扩展到包含多个项目的多个列表。试试看,告诉我进展如何。

    • 制作列表的哈希表
    • 对于每个列表,将列表中的第n个元素存储在键
      (/n(+(长度列表)1))
    • (可选)洗牌哈希表中每个键下的列表,或以某种方式对它们进行排序
    • 按排序键连接散列中的列表
    实施 安德鲁·罗林斯的回答:

    公共列表equimix(列表输入){
    //将最大列表排序为最小列表
    Collections.sort(输入,新的Comparator(){
    公共整数比较(列表a1、列表a2){
    返回a2.size()-a1.size();
    }
    });
    列表输出=输入。获取(0);
    对于(int i=1;ilistA.size()){
    列表温度;
    temp=listB;
    listB=listA;
    listA=温度;
    }
    列表输出=listA;
    double-shiftceff=(double)listA.size()/listB.size();
    双浮点计数器=移位效率;
    用于(字符串项:listB){
    int insertionIndex=(int)Math.round(floatCounter);
    输出.添加(插入索引,项);
    浮动计数器+=(1+shiftcoff);
    }
    返回输出;
    }
    
    听起来像是将元素随机化。虽然它可能在大多数情况下都会起作用,但有时你会得到一个相当不平衡的分布。是的,我在发布我的解决方案后注意到了。这会比Will的答案更好吗?在我看来,你不只是想将它们结合起来,你希望它们像拉链一样均匀地融合在一起,或者像汽车在高速公路上礼貌地融合在一起。我说的对吗?这个算法有一个众所周知的名字吗?在这一点上的一个变体是使用Bresenham的直线算法,而不是步骤4中的浮点计数器。将N个对象均匀地插入到现有的M个对象列表中,相当于从到枚举光栅化线的点。。。溢出/舍入是bresenhams的核心。@AndrewRollings你能详细解释一下吗,或者一个
    伪代码
    对我来说就足够理解了?我无法清楚地理解您的答案。此伪代码并非在所有情况下都有效。我实现了它,并尝试使用大小为2和6的两个列表。试图从空列表中删除元素时出现索引器错误。