同源设置连接

时间:2017-09-23 17:58:19

标签: algorithm sorting math

我正在寻找可以解决这种情况的算法:

假设我有3套(但我可以有更多),每套都包含不同数量的元素:

A = [⚫️, ⚫️, ⚫️]

B = [, , , , ]

C = [, , , , , , , ]

如何将它们连接成一个独特的集合,尽可能均匀地分布它们的元素?例如:

D = [⚫️, , , , , , ⚫️, , , , , ⚫️, , , , ]

真正的利害关系是处理分配不完美的情况(如上例所示)。

任何可以帮助我的想法/知识?

2 个答案:

答案 0 :(得分:0)

您可以将每个列表的元素映射到区间[0,1],并根据指定的位置对所有元素进行排序。如果两个元素映射到相同的位置,则按照列表的顺序放置它们。

以下是Python实现示例 - 索引为i的元素(基于0)映射到位置(i + 0.5) / len(list)

def mix(lists):
    elements = []
    for li, list in enumerate(lists):
        for ei, e in enumerate(list):
            elements.append(((ei + 0.5)/len(list), li, e))
    elements.sort()
    return [e for p, li, e in elements]

>>> ''.join(mix(["222", "11111", "00000000"]))
'0120100210010210'

还可以通过使用优先级队列来实现使用更少内存的实现。

答案 1 :(得分:0)

这是一个Python解决方案,可以执行您可能需要的操作。我所做的是做一个Schwartzian变换,使每个元素“知道”它应该在输出中的位置,然后对它进行排序。

请注意,它是O(n log(n)),可以轻松修改为O(n)。这也可以通过各种方式进行调整。但这不是一个糟糕的第一关。

我写的语言是Python。

def merge_arrays (*arrays):
    sortable_arrays = []
    for array in arrays:
        length = len(array) + 0.0 # Make it floating point.
        if 0.0 < length:
            sortable_arrays.append([
                    [
                        i/(length-1.0), # Ideal spot for each element.
                        (i+0.5)/length, # Break ties with bigger arrays outside
                        array[i], # our element.
                    ] for i in xrange(len(array))
                ])

    merged = sorted(sum(sortable_arrays, []))
    return [x[2] for x in merged]

print(" ".join(merge_arrays(['A']*3, ['B']*5, ['C']*8)))

输出结果为:

C B A C B C C A B C C B C A B C